Partager via


Étape 7 : Implémenter le gestionnaire de trafic sortant synchrone pour l’adaptateur Echo

Étape 7 sur 9

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

  1. Dans Explorateur de solutions, double-cliquez sur le fichier EchoAdapterOutboundHandler.cs.

  2. Dans l’éditeur Visual Studio, ajoutez les deux directives using suivantes à l’ensemble existant de directives using.

    using System.Xml;  
    using System.IO;  
    
  3. Dans la méthode Execute , remplacez la logique existante par ce qui suit :

    1. Cette logique vérifie l’opération demandée.

    2. Il obtient l’objet Microsoft.ServiceModel.Channels.Common.OperationMetadata en fonction de l’action de message d’entrée SOAP.

    3. 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;              
    
  4. 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);  
    }  
    
  5. 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 et ResolveTypeMetadata de l’interface Microsoft.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);  
    }  
    
  6. 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);  
    }  
    
  7. Dans Visual Studio, dans le menu Fichier , cliquez sur Enregistrer tout.

  8. 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