Étape 7 : Implémenter le gestionnaire de trafic sortant synchrone pour l’adaptateur Echo
Durée d’exécution : 30 minutes
Dans cette étape, vous implémentez la fonctionnalité sortante synchrone de l’adaptateur Echo. Selon le Kit de développement logiciel (SDK) de l’adaptateur LOB WCF, pour prendre en charge la fonctionnalité sortante synchrone, vous devez implémenter l’interface Microsoft.ServiceModel.Channels.Common.IOutboundHandler
. Pour l’adaptateur Echo, l’Assistant Développement d’adaptateur génère automatiquement une classe dérivée appelée EchoAdapterOutboundHandler.
Dans les sections suivantes, vous mettez à jour la classe EchoAdapterOutboundHandler pour mieux comprendre comment implémenter le Microsoft.ServiceModel.Channels.Common.IOutboundHandler.Execute%2A
, comment analyser le message de requête WCF entrant et comment générer des messages de réponse WCF sortants.
Prérequis
Avant de commencer cette étape, vous devez avoir terminé l’étape 6 : Implémenter le gestionnaire de résolution des métadonnées pour l’adaptateur Echo. Une connaissance de base est Microsoft.ServiceModel.Channels.Common.IOutboundHandler
également utile.
The IOutboundHandler Interface
Le Microsoft.ServiceModel.Channels.Common.IOutboundHandler
est défini comme :
public interface IOutboundHandler : IConnectionHandler, IDisposable
{
Message Execute(Message message, TimeSpan timeout);
}
La Microsoft.ServiceModel.Channels.Common.IOutboundHandler.Execute%2A
méthode exécute le message de requête WCF entrant en appelant la méthode correspondante sur le système cible, puis retourne un message de réponse WCF sortant. Les définitions de ses paramètres sont répertoriées dans le tableau suivant :
Paramètre | Définition |
---|---|
message | Message de demande WCF entrante. |
timeout | Intervalle de temps pendant lequel cette opération doit être effectuée. L’opération doit lever un System.TimeoutException si le délai d’expiration spécifié est dépassé avant la fin de l’opération. |
Si votre adaptateur effectue un envoi unidirectionnel (aucun message de réponse n’est attendu par votre adaptateur), cette méthode doit retourner la valeur Null. Si votre adaptateur effectue une opération bidirectionnelle avec Microsoft.ServiceModel.Channels.Common.OperationResult
égal à Microsoft.ServiceModel.Channels.Common.OperationResult.Empty%2A
, cette méthode retourne un message de réponse WCF avec un corps vide. Sinon, il doit retourner le message de réponse WCF avec un corps qui contient les valeurs de l’objet Microsoft.ServiceModel.Channels.Common.OperationResult
. Pour construire la chaîne d’action de réponse, utilisez Microsoft.ServiceModel.Channels.Common.OperationMetadata.OutputMessageAction%2A
.
Sortie synchrone de l’adaptateur Echo
Selon les opérations de votre système cible, il existe de nombreuses façons d’implémenter la Microsoft.ServiceModel.Channels.Common.IOutboundHandler.Execute%2A
méthode. Pour l’adaptateur Echo, il existe trois opérations sortantes, et leurs ID de nœud et leurs noms complets attribués sont les suivants :
string[] EchoStrings(string data), node ID = Echo/EchoString, display name=EchoString
Greeting[] EchoGreetings(Greeting greeting), node ID=Echo/EchoGreetings, display name=EchoGreetings
CustomGreeting EchoCustomGreetingFromFile(Uri greetingInstancePath), nodeID=Echo/EchoCustomGreetingFromFile, nom d’affichage=EchoGreetings
Pour analyser correctement le message de requête WCF entrant et générer le message de réponse WCF sortant, vous devez être familiarisé avec les éléments suivants dans le message SOAP utilisé par le Kit de développement logiciel (SDK) de l’adaptateur WCF LOB :
Pour le message de demande WCF entrante :
Action de message d’entrée WCF = ID de nœud de l’opération
Corps du message entrant = L’élément start du corps est <displayname><parameter name>{data}</parameter name></displayname>
Pour le message de réponse WCF sortant :
Action de message de sortie WCF = ID de nœud de l’opération + « /response »
Corps du message sortant = l’élément de début du corps est <displayname + « Response »,> suivi de <displayname + « Result »,> et suivi de datatype <>data</datatype></displayname+"Result></displayname + « Response »>
Par exemple, operation string[] EchoStrings(string data), node ID = Echo/EchoStrings, and display name= EchoStrings :
L’action de message d’entrée WCF = « Echo/EchoStrings » ; et le corps d’entrée se présente comme suit, car le nom du paramètre est
data
.
<EchoStrings>
<data>{data}
</data>
</EchoStrings>
L’action de message de sortie WCF = « Echo/EchoStrings/response » ; et le corps de sortie se présente comme suit, car le type de données est string.
<EchoStringsResponse>
<EchoStringsResult>
<string>{data}</string>
</EchoStringsResult>
</EchoStringsResponse>
Lors de l’analyse du message de requête WCF entrant, vous pouvez utiliser pour récupérer le System.Xml.XmlDictionaryReader
contenu dans le message WCF ; lors de la composition du message de réponse WCF, vous pouvez utiliser le System.Xml.XmlWriter
pour ce faire.
Implémentation du gestionnaire IOutboundHandler
Vous implémentez la méthode Execute du Microsoft.ServiceModel.Channels.Common.IOutboundHandler
. Tout d’abord, obtient un Microsoft.ServiceModel.Channels.Common.OperationMetadata
objet basé sur l’action de message d’entrée. Ensuite, analyse le message WCF entrant et exécute la fonctionnalité d’écho associée en fonction de chaque opération. Enfin, crée un message de réponse WCF sortant en utilisant le format du corps du message sortant.
Pour implémenter la méthode Execute de la classe EchoAdapterOutboundHandler
Dans Explorateur de solutions, double-cliquez sur le fichier EchoAdapterOutboundHandler.cs.
Dans l’éditeur Visual Studio, ajoutez les deux directives using suivantes à l’ensemble existant de directives using.
using System.Xml; using System.IO;
Dans la méthode Execute , remplacez la logique existante par ce qui suit :
Cette logique vérifie l’opération demandée.
Il obtient l’objet
Microsoft.ServiceModel.Channels.Common.OperationMetadata
en fonction de l’action de message d’entrée SOAP.En fonction du type d’action, il analyse le message de requête WCF et appelle l’opération appropriée.
// Trace input message EchoAdapterUtilities.Trace.Trace(System.Diagnostics.TraceEventType.Verbose, "http://Microsoft.Adapters.Samples.Sql/TraceCode/InputWcfMessage", "Input WCF Message", this, new MessageTraceRecord(message)); // Timeout is not supported in this sample OperationMetadata om = this.MetadataLookup.GetOperationDefinitionFromInputMessageAction(message.Headers.Action, timeout); if (om == null) { throw new AdapterException("Invalid operation metadata for " + message.Headers.Action); } if (timeout.Equals(TimeSpan.Zero)) { throw new AdapterException("time out is zero"); } switch (message.Headers.Action) { case "Echo/EchoStrings": return ExecuteEchoStrings(om as ParameterizedOperationMetadata, message, timeout); case "Echo/EchoGreetings": return ExecuteEchoGreetings(om as ParameterizedOperationMetadata, message, timeout); case "Echo/EchoCustomGreetingFromFile": return ExecuteEchoCustomGreetingFromFile(om, message, timeout); } return null;
Ajoutez maintenant la méthode ExecuteEchoStrings pour gérer l’opération string[] EchoStrings(string data). Cette fonction d’assistance lit le message de requête WCF, vérifie si l’élément URI echoInUpperCase a la valeur true ; si c’est le cas, il convertit la chaîne d’entrée en majuscules autant de fois que la variable count l’indique. Ensuite, il génère le message de réponse WCF au format : EchoStringsResponse><EchoStringResult><string>{data}</string></EchoStringResult></EchoStringsResponse>. <
private Message ExecuteEchoStrings(ParameterizedOperationMetadata om, Message message, TimeSpan timeout) { // ** Read the WCF request // ** <EchoStrings><name>{text}</name></EchoStrings> XmlDictionaryReader inputReader = message.GetReaderAtBodyContents(); while (inputReader.Read()) { if ((String.IsNullOrEmpty(inputReader.Prefix) && inputReader.Name.Equals("data")) || inputReader.Name.Equals(inputReader.Prefix + ":" + "data")) break; } inputReader.Read(); // if the connection property "echoInUpperCase" is set to true, it echoes the data in upper case bool echoInUpperCase = this.Connection.ConnectionFactory.ConnectionUri.EchoInUpperCase; string inputValue = echoInUpperCase ? inputReader.Value.ToUpper() : inputReader.Value; int arrayCount = this.Connection.ConnectionFactory.Adapter.Count; // ** Generate the WCF response // ** <EchoStringsResponse><EchoStringResult>{Name}</EchoStringResult></EchoStringsResponse > StringBuilder outputString = new StringBuilder(); XmlWriterSettings settings = new XmlWriterSettings(); settings.OmitXmlDeclaration = true; XmlWriter replywriter = XmlWriter.Create(outputString, settings); replywriter.WriteStartElement(om.DisplayName + "Response", EchoAdapter.SERVICENAMESPACE); replywriter.WriteStartElement(om.DisplayName + "Result", EchoAdapter.SERVICENAMESPACE); if (om.OperationResult.IsArray) { for (int count = 0; count < arrayCount; count++) { replywriter.WriteElementString("string", "http://schemas.microsoft.com/2003/10/Serialization/Arrays", inputValue); } } replywriter.WriteEndElement(); replywriter.WriteEndElement(); replywriter.Close(); XmlReader replyReader = XmlReader.Create(new StringReader(outputString.ToString())); return Message.CreateMessage(message.Version, om.OutputMessageAction, replyReader); }
Continuez en ajoutant la méthode ExecuteEchoGreetings pour gérer l’opération EchoGreetings. Cette fonction d’assistance lit le message de requête WCF, résout l’opération et le type par les
ResolveOperationMetadata
méthodes etResolveTypeMetadata
de l’interfaceMicrosoft.ServiceModel.Channels.Common.IMetadataResolverHandler
, puis génère le message de réponse WCF au format : <EchoGreetingsResponse><EchoGreetingsResult>... Message...</EchoGreetingsResult></EchoGreetingsResponse>.private Message ExecuteEchoGreetings(ParameterizedOperationMetadata om, Message message, TimeSpan timeout) { // NOTE this method doesn't return response in upper case based on // connection property echoInUpperCase // ** Read the WCF request String inputValue = String.Empty; using (XmlDictionaryReader inputReader = message.GetReaderAtBodyContents()) { bool foundGreeting = inputReader.ReadToDescendant("greeting"); if (foundGreeting) { inputValue = inputReader.ReadInnerXml(); } } int arrayCount = this.Connection.ConnectionFactory.Adapter.Count; // ** Generate the WCF response StringBuilder outputString = new StringBuilder(); XmlWriterSettings settings = new XmlWriterSettings(); settings.OmitXmlDeclaration = true; XmlWriter replywriter = XmlWriter.Create(outputString, settings); replywriter.WriteStartElement(om.DisplayName + "Response", EchoAdapter.SERVICENAMESPACE); replywriter.WriteStartElement(om.DisplayName + "Result", EchoAdapter.SERVICENAMESPACE); for(int i = 0; i < arrayCount; i++ ) { ComplexQualifiedType cqtResult = om.OperationResult.QualifiedType as ComplexQualifiedType; StructuredTypeMetadata tmResult = MetadataLookup.GetTypeDefinition(cqtResult.TypeId, timeout) as StructuredTypeMetadata; replywriter.WriteStartElement(tmResult.TypeName, tmResult.TypeNamespace); replywriter.WriteRaw(inputValue); replywriter.WriteEndElement(); } replywriter.WriteEndElement(); replywriter.WriteEndElement(); replywriter.Close(); XmlReader replyReader = XmlReader.Create(new StringReader(outputString.ToString())); return Message.CreateMessage(message.Version, om.OutputMessageAction, replyReader); }
Ajoutez maintenant la méthode ExecuteEchoCustomGreetingFromFile pour gérer l’opération EchoCustomGreetingFromFile. Cette fonction d’assistance lit le message de requête WCF, lit le message à partir du fichier spécifié, puis génère le message de réponse WCF au format : <EchoGreetingsFromFileResponse><EchoGreetingsFromFileResult>... Message...</EchoGreetingsFromFileResult></EchoGreetingsFromFileResponse>.
private Message ExecuteEchoCustomGreetingFromFile(OperationMetadata om, Message message, TimeSpan timeout) { // NOTE this method doesn't return response in upper case based on // connection property echoInUpperCase // ** Read the WCF request Uri path; using (XmlDictionaryReader inputReader = message.GetReaderAtBodyContents()) { inputReader.MoveToContent(); inputReader.ReadStartElement(om.DisplayName); inputReader.MoveToContent(); // The path contains the location of the XML file that contains the instance of Greeting object to read path = new Uri(inputReader.ReadElementContentAsString()); inputReader.ReadEndElement(); } // ** Generate the WCF response StringBuilder outputString = new StringBuilder(); XmlWriterSettings settings = new XmlWriterSettings(); settings.OmitXmlDeclaration = true; XmlWriter replywriter = XmlWriter.Create(outputString, settings); replywriter.WriteStartElement(om.DisplayName + "Response", EchoAdapter.SERVICENAMESPACE); replywriter.WriteStartElement(om.DisplayName + "Result", EchoAdapter.SERVICENAMESPACE); // Read the XML file and set it to the reply writer here FileStream stream = new FileStream(path.AbsolutePath, FileMode.Open); XmlDictionaryReader xdr = XmlDictionaryReader.CreateTextReader(stream, new XmlDictionaryReaderQuotas()); xdr.MoveToContent(); string rawGreeting = xdr.ReadInnerXml(); replywriter.WriteRaw(rawGreeting); replywriter.WriteEndElement(); replywriter.WriteEndElement(); replywriter.Close(); XmlReader replyReader = XmlReader.Create(new StringReader(outputString.ToString())); return Message.CreateMessage(message.Version, om.OutputMessageAction, replyReader); }
Dans Visual Studio, dans le menu Fichier , cliquez sur Enregistrer tout.
Dans le menu Générer, cliquez sur Générer la solution. Elle doit être compilée sans erreurs. Si ce n’est pas le cas, vérifiez que vous avez suivi toutes les étapes ci-dessus. À présent, vous pouvez fermer Visual Studio en toute sécurité ou passer à l’Étape 8 : Implémenter le gestionnaire entrant synchrone pour l’adaptateur Echo.
Qu’est-ce que je viens de faire ?
Dans cette étape, vous avez appris à implémenter la fonctionnalité de messagerie sortante synchrone de l’adaptateur Echo. Pour ce faire, vous avez implémenté la Microsoft.ServiceModel.Channels.Common.IOutboundHandler.Execute%2A
méthode du Microsoft.ServiceModel.Channels.Common.IOutboundHandler
. Cette méthode a analysé le message de requête WCF entrant, effectué les actions nécessaires, puis généré le message de réponse WCF sortant.
Plus précisément, pour le message de requête WCF entrant, vous avez utilisé WCF System.ServiceModel.Channels.Message.Headers.Action%2A
pour récupérer l’action de message d’entrée en comprenant davantage la structure de base du corps du message entrant. Pour le message de réponse WCF sortant, vous avez utilisé Microsoft.ServiceModel.Channels.Common.OperationMetadata.OutputMessageAction%2A
pour récupérer l’action de message de sortie en approfondissant la structure de base du corps du message sortant. Lors de l’analyse et de la composition de messages WCF, vous avez utilisé System.Xml.XmlDictionaryReader
pour lire le message de requête WCF entrant et utilisé System.Xml.XmlWriter
pour écrire un message de réponse WCF sortant.
Étapes suivantes
Générez et déployez l’adaptateur Echo.
Voir aussi
Étape 6 : Implémenter le gestionnaire de résolution des métadonnées pour l’adaptateur Echo
Étape 8 : Implémenter le gestionnaire de trafic entrant synchrone pour l’adaptateur Echo