Partager via


Operation Formatter and Operation Selector

L’exemple QueryStringFormatter montre comment les points d’extensibilité WCF (Windows Communication Foundation) peuvent être utilisés pour autoriser l’utilisation des données de message dans un format différent de celui attendu par WCF. Par défaut, les formateurs WCF s’attendent à ce que des paramètres de méthode soient inclus sous l’élément soap:body. L'exemple montre comment implémenter à la place un formateur d'opération personnalisé qui analyse les données de paramètre d'une chaîne de requête HTTP GET chaîne et appelle des méthodes à l'aide de ces données.

Cet exemple est basé sur la Prise en main, qui implémente le contrat de service ICalculator. Il montre comment les messages d'ajout, de soustraction, de multiplication et de division peuvent être modifiés pour utiliser HTTP GET pour les demandes de client à serveur et HTTP POST avec messages POX pour les réponses de serveur à client.

Pour cela, l'exemple fournit les éléments suivants :

  • QueryStringFormatter, qui implémente IClientMessageFormatter et IDispatchMessageFormatter pour le client et le serveur respectivement, et traite les données dans la chaîne de requête.

  • UriOperationSelector, qui implémente IDispatchOperationSelector sur le serveur pour effectuer la distribution des opérations en fonction du nom de l'opération dans la demande GET.

  • Comportement de point de terminaison EnableHttpGetRequestsBehavior (et configuration correspondante), qui ajoute le sélecteur d'opération nécessaire à l'exécution.

  • Indique comment insérer un nouveau formateur d'opération dans l'exécution.

  • Dans cet exemple, le client et le service sont tous deux des applications consoles (.exe).

Notes

La procédure d'installation ainsi que les instructions de génération relatives à cet exemple figurent à la fin de cette rubrique.

Concepts clés

QueryStringFormatter : le formateur d’opération est le composant de WCF chargé de convertir un message en un tableau d’objets de paramètre et vice versa. Cela est effectué sur le client à l'aide de l'interface IClientMessageFormatter et sur le serveur avec l'interface IDispatchMessageFormatter. Ces interfaces permettent aux utilisateurs d'obtenir les messages de demande et de réponse des méthodes Serialize et Deserialize.

Dans cet exemple, QueryStringFormatter implémente ces deux interfaces et est implémenté sur le client et le serveur.

Demande :

  • L'exemple utilise la classe TypeConverter pour convertir les données de paramètre du message de demande en chaînes et vice versa. Si un TypeConverter n'est pas disponible pour un type spécifique, l'exemple de formateur lève une exception.

  • Dans la méthode IClientMessageFormatter.SerializeRequest sur le client, le formateur crée un URI avec l''adresse To appropriée et ajoute le nom d'opération en tant que suffixe. Ce nom est utilisé pour la distribution à l'opération appropriée sur le serveur. Il prend ensuite le tableau d'objets de paramètre et sérialise les données de paramètre dans la chaîne de requête URI à l'aide des noms de paramètre et des valeurs converties par la classe TypeConverter. Cette valeur est affectée aux propriétés To et Via, puis à cet URI. MessageProperties est accessible à l'aide de la propriété Properties.

  • Dans la méthode IDispatchMessageFormatter.DeserializeRequest sur le serveur, le formateur récupère l'URI Via dans les propriétés de message de la demande entrante. Il analyse les paires nom-valeur dans la chaîne de requête URI en fonction des noms de paramètre et des valeurs et utilise les noms de paramètre et les valeurs pour compléter le tableau de paramètres passé dans la méthode. Notez que la distribution des opérations s'est déjà produite, donc le suffixe du nom de l'opération est ignoré dans cette méthode.

Réponse :

  • Dans cet exemple, HTTP GET est utilisé uniquement pour la demande. Le formateur délègue l'envoi de la réponse au formateur d'origine qui aurait été utilisé pour générer un message XML. L'un des objectifs de cet exemple est de montrer comment un tel formateur déléguant peut être implémenté.

Classe UriPathSuffixOperationSelector

L'interface IDispatchOperationSelector permet aux utilisateurs d'implémenter leur propre logique pour indiquer pour quelle opération un message particulier doit être distribué.

Dans cet exemple, UriPathSuffixOperationSelector doit être implémenté sur le serveur pour sélectionner l'opération appropriée parce que le nom de l'opération est inclus dans l'URI HTTP GET plutôt que dans un en-tête d'action dans le message. L'exemple est configuré pour des noms d'opération non sensibles à la casse uniquement.

La méthode SelectOperation prend le message entrant et recherche l'URI Via dans ses propriétés de message. Elle extrait le suffixe du nom de l'opération de l'URI, recherche une table interne pour obtenir le nom de l'opération à laquelle le message doit être distribué, et retourne ce nom d'opération.

Classe EnableHttpGetRequestsBehavior

Le composant UriPathSuffixOperationSelector peut être installé par programme ou par l'intermédiaire d'un comportement de point de terminaison. L’exemple implémente le comportement EnableHttpGetRequestsBehavior, spécifié dans le fichier de configuration de l’application du service.

Sur le serveur :

Le OperationSelector a pour valeur l'implémentation IDispatchOperationSelector.

Par défaut, WCF utilise un filtre d’adresse de correspondance exacte. L'URI sur le message entrant contient un suffixe de nom d'opération suivi par une chaîne de requête qui contient des données de paramètre, donc le comportement de point de terminaison modifie également le filtre d'adresse en filtre de correspondance du préfixe. Il utilise le PrefixEndpointAddressMessageFilter WCF à cette fin.

Installation des formateurs d'opération

Les comportements d'opération qui spécifient des formateurs sont uniques. Un tel comportement est toujours implémenté par défaut pour chaque opération pour créer le formateur d'opération nécessaire. Toutefois, ces comportements ressemblent à tous les autres comportements d'opération ; ils ne sont pas identifiables par tout autre attribut. Pour installer un comportement de remplacement, l’implémentation doit rechercher des comportements de formateur spécifiques installés par défaut par le chargeur de type WCF et soit le remplacer, soit ajouter un comportement compatible à exécuter après le comportement par défaut.

Ces comportements de formateur d'opération peuvent être installés par programme avant d'appeler CommunicationObject.Open ou en spécifiant un comportement d'opération exécuté après le comportement par défaut. Cependant, ils ne peuvent pas être installés facilement par un comportement de point de terminaison (et par conséquent par la configuration) parce que le modèle de comportement ne permet pas à un comportement de remplacer d’autres comportements ou modifier de toute autre manière l’arborescence de description.

Sur le client :

L'implémentation IClientMessageFormatter doit être implémentée afin qu'elle puisse convertir les demandes en demandes HTTP GET et déléguer les réponses au formateur d'origine. Cela est effectué en appelant la méthode d'assistance EnableHttpGetRequestsBehavior.ReplaceFormatterBehavior.

Ceci doit être fait avant d'appeler CreateChannel.

void ReplaceFormatterBehavior(OperationDescription operationDescription, EndpointAddress address)
{
    // Remove the DataContract behavior if it is present.
    IOperationBehavior formatterBehavior = operationDescription.Behaviors.Remove<DataContractSerializerOperationBehavior>();
    if (formatterBehavior == null)
    {
        // Remove the XmlSerializer behavior if it is present.
        formatterBehavior = operationDescription.Behaviors.Remove<XmlSerializerOperationBehavior>();
        ...
    }

    // Remember what the innerFormatterBehavior was.
    DelegatingFormatterBehavior delegatingFormatterBehavior = new DelegatingFormatterBehavior(address);
    delegatingFormatterBehavior.InnerFormatterBehavior = formatterBehavior;
   operationDescription.Behaviors.Add(delegatingFormatterBehavior);
}

Sur le serveur :

  • L'interface IDispatchMessageFormatter doit être implémentée afin qu'elle puisse lire les demandes HTTP GET et déléguer l'écriture des réponses au formateur d'origine. Cela est effectué en appelant la même méthode d'assistance EnableHttpGetRequestsBehavior.ReplaceFormatterBehavior que le client (consultez l'exemple de code précédent).

  • Ceci doit être fait avant d'appeler Open. Dans cet exemple, nous montrons comment le formateur est modifié manuellement avant d'appeler Open. Pour parvenir au même résultat, il est possible de dériver une classe de ServiceHost qui appelle EnableHttpGetRequestsBehavior.ReplaceFormatterBehavior avant de s'ouvrir (consultez la documentation et les exemples relatifs à l'hébergement).

Expérience utilisateur

Sur le serveur :

  • L'implémentation serveur ICalculator n'a pas besoin d'être modifiée.

  • L’App.config pour le service doit utiliser une liaison POX personnalisée qui affecte à l’attribut messageVersion de l’élément textMessageEncoding la valeur None.

    <bindings>
      <customBinding>
        <binding name="poxBinding">
          <textMessageEncoding messageVersion="None" />
          <httpTransport />
        </binding>
      </customBinding>
    </bindings>
    
  • L’App.config pour le service doit également spécifier le EnableHttpGetRequestsBehavior personnalisé en l’ajoutant à la section d’extensions de comportement et en l’utilisant.

    <behaviors>
      <endpointBehaviors>
        <behavior name="enableHttpGetRequestsBehavior">
          <enableHttpGetRequests />
        </behavior>
      </endpointBehaviors>
    </behaviors>
    
    <extensions>
      <behaviorExtensions>
        <!-- Enabling HTTP GET requests: Behavior Extension -->
        <add
          name="enableHttpGetRequests"           type="Microsoft.ServiceModel.Samples.EnableHttpGetRequestsBehaviorElement, QueryStringFormatter, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      </behaviorExtensions>
    </extensions>
    
  • Ajoutez les formateurs d'opération avant d'appeler Open.

Sur le client :

  • L'implémentation cliente n'a pas besoin d'être modifiée.

  • L’App.config pour le client doit utiliser une liaison POX personnalisée qui affecte à l’attribut messageVersion de l’élément textMessageEncoding la valeur None. À la différence du service, le client doit activer l'adressage manuel afin que l'adresse To sortante puisse être modifiée.

    <bindings>
      <customBinding>
        <binding name="poxBinding">
          <textMessageEncoding messageVersion="None" />
          <httpTransport manualAddressing="True" />
        </binding>
      </customBinding>
    </bindings>
    
  • L'App.config pour le client doit spécifier le même EnableHttpGetRequestsBehavior personnalisé que le serveur.

  • Ajoutez les formateurs d'opération avant d'appeler CreateChannel().

Lorsque vous exécutez l'exemple, les demandes et réponses d'opération s'affichent dans la fenêtre de console du client. Les quatre opérations (addition, soustraction, multiplication et division) doivent réussir.

Pour configurer, générer et exécuter l'exemple
  1. Assurez-vous d’avoir effectué la Procédure d’installation unique pour les exemples Windows Communication Foundation.

  2. Pour générer la solution, suivez les instructions indiquées dans la rubrique Génération des exemples Windows Communication Foundation.

  3. Pour exécuter l’exemple dans une configuration à un ou plusieurs ordinateurs, conformez-vous aux instructions figurant dans la rubrique Exécution des exemples Windows Communication Foundation.