Procédure pas à pas : personnalisation de la génération des descriptions de service et des classes proxy

Cette rubrique est spécifique à une technologie existante. Les services Web XML et les clients du service Web XML doivent à présent être créés à l'aide de Windows Communication Foundation.

La génération de la description de service et des classes proxy d'un service Web créé à l'aide d'ASP.NET peut être étendue via la création et l'installation d'une extension de format de description de service (SDFE). Plus précisément, une SDFE peut ajouter des éléments XML à la description de service (le document Web Services Description Language (WSDL) d'un service Web) et ajouter des attributs personnalisés à une méthode qui communique avec un service Web.

Les SDFE sont particulièrement utiles lorsqu'une extension SOAP doit s'exécuter à la fois avec un service Web et ses clients ; par défaut, aucune information sur les extensions SOAP n'est placée ni dans la description de service, ni dans les classes proxy générées pour elles. Par exemple, une extension SOAP de chiffrement doit être exécutée à la fois sur le client et sur le serveur. Si une extension SOAP de chiffrement s'exécute sur le serveur pour chiffrer la réponse SOAP, le client doit exécuter l'extension SOAP pour déchiffrer le message. Une SDFE peut ajouter des éléments à la description de service pour informer des clients qu'une extension SOAP doit s'exécuter, et la SDFE peut étendre le processus de génération de classe proxy pour ajouter un attribut personnalisé à la classe proxy, ce qui entraîne l'exécution de l'extension SOAP par la classe. Cette procédure pas à pas décrit les tâches suivantes :

  1. Définition du XML à ajouter à la description de service.

  2. Création d'une classe SDFE en dérivant de la classe ServiceDescriptionFormatExtension.

  3. Écriture du code pour étendre le processus de génération de description du service.

  4. Écriture du code pour étendre le processus de génération de classe proxy.

  5. Configuration de la SDFE pour qu'elle s'exécute à la fois sur le client et le serveur.

Définition du XML et création de la classe SDFE

Les exemples de code dans cette procédure pas à pas impliquent une classe ServiceDescriptionFormateExtension``YMLOperationBinding pour une classe SoapExtension``YMLExtension. Le code complet est présenté dans la rubrique Comment : personnaliser la génération des descriptions de service et des classes proxy (Exemple de code).

Pour définir le XML à ajouter à la description de service

  1. Choisissez le XML à ajouter à la description de service.

    L'exemple de code suivant est la partie d'une description de service à laquelle la SDFE d'exemple ajoute des éléments XML. Plus précisément, la SDFE d'exemple déclare un préfixe d'espace de noms XML yml dans l'élément definitions racine d'un document WSDL et applique cet espace de noms à l'élément yml:action (et ses éléments enfants) qui apparaît dans la liaison des éléments operation.

    <definitions ...
      xmlns:yml="https://www.contoso.com/yml" >
      ...
      <binding name="HelloWorldSoap" type="s0:HelloWorldSoap">
        <soap:binding transport="https://schemas.xmlsoap.org/soap/http"
                    style="document" /> 
          <operation name="SayHello">
            <soap:operation soapAction="http://tempuri.org/SayHello"
                        style="document" />
            <yml:action>
              <yml:Reverse>true</yml:Reverse> 
            </yml:action>
          </operation>
          ...
      </binding>
      ... 
    </definitions>
    
  2. Créez une classe qui dérive de ServiceDescriptionFormatExtension.

    Lorsque vous utilisez Visual Studio .NET, ajoutez une référence à l'assembly System.Web.Services. Ajoutez également un déclaration using ou Imports au fichier pour l'espace de noms System.Web.Services.Description.

    L'exemple de code suivant crée la classe YMLOperationBinding qui dérive de ServiceDescriptionFormatExtension.

    Public Class YMLOperationBinding
        Inherits ServiceDescriptionFormatExtension
    
    public class YMLOperationBinding : ServiceDescriptionFormatExtension
    
  3. Appliquez un XmlFormatExtensionAttribute à la classe.

    Cet attribut spécifie l'étape du processus de génération de description de service à laquelle la SDFE s'exécute, également appelée point d'extension. Le tableau suivant répertorie les points d'extension définis et les éléments XML WSDL générés pendant chaque point. Pour le point d'extension spécifié, l'élément WSDL correspondant devient le parent de l'élément qui est ajouté.

    Point d'extension Description

    ServiceDescription

    Correspond à l'élément definitions racine d'un document WSDL.

    Types

    Correspond à l'élément types joint par l'élément definitions racine.

    Binding

    Correspond à l'élément binding joint par l'élément definitions racine.

    OperationBinding

    Correspond à l'élément operation joint par l'élément binding.

    InputBinding

    Correspond à l'élément input joint par l'élément operation.

    OutputBinding

    Correspond à l'élément output joint par l'élément operation.

    FaultBinding

    Correspond à l'élément fault joint par l'élément operation.

    Port

    Correspond à l'élément port joint par l'élément service.

    Operation

    Correspond à l'élément operation joint par l'élément portType.

    Lorsque vous appliquez un XmlFormatExtensionAttribute à la classe, vous spécifiez également le nom d'élément XML et l'espace de noms XML devant contenir les éléments XML à ajouter à la description de service.

    L'exemple de code suivant spécifie que la SDFE YMLOperationBinding ajoute un élément XML nommé <action xmlns="https://www.contoso.com/yml">OperationBinding à la description de service pendant le point d'extension. Pour cet exemple, l'espace de noms https://www.contoso.com/yml XML est spécifié ultérieurement lorsque le champ YMLOperationBinding.YMLNamespace est ajouté à la classe.

    <XmlFormatExtension("action", YMLOperationBinding.YMLNamespace, _
                        GetType(OperationBinding))> _
    Public Class YMLOperationBinding
        Inherits ServiceDescriptionFormatExtension
    
    [XmlFormatExtension("action", YMLOperationBinding.YMLNamespace,
                        typeof(OperationBinding))]
    public class YMLOperationBinding : ServiceDescriptionFormatExtension
    
  4. Éventuellement, appliquez un XmlFormatExtensionPrefixAttribute à la classe pour associer le préfixe d'espace de noms XML à l'espace de noms XML utilisé par la SDFE.

    L'exemple de code suivant spécifie que le préfixe d'espace de noms XML yml est associé à l'espace de noms https://www.contoso.com/yml dans l'élément definitions de la description de service. En outre, le préfixe est utilisé dans les éléments ajoutés par la SDFE au lieu de l'espace de noms. Par conséquent, l'élément XML ajouté à la description de service à l'étape 3 utilise désormais le préfixe d'espace de noms et donc l'élément ajouté est <yml:action> au lieu de <action xmlns="https://www.contoso.com/yml">.

    <XmlFormatExtension("action", YMLOperationBinding.YMLNamespace, _
                        GetType(OperationBinding)), _
     XmlFormatExtensionPrefix("yml", YMLOperationBinding.YMLNamespace)> _
    Public Class YMLOperationBinding
         Inherits ServiceDescriptionFormatExtension
    
    [XmlFormatExtension("action", YMLOperationBinding.YMLNamespace,
                        typeof(OperationBinding))]
    [XmlFormatExtensionPrefix("yml", YMLOperationBinding.YMLNamespace)]
    public class YMLOperationBinding : ServiceDescriptionFormatExtension 
    
  5. Ajoutez des propriétés et des champs publics à la classe qui représente le XML à ajouter au document WSDL. L'exemple de code suivant ajoute une propriété publique Reverse sérialisée dans un élément <yml:Reverse>value</yml:Reverse> dans le WSDL.

    Private _reverse As Boolean
    <XmlElement("Reverse")> _
    Public Property Reverse() As Boolean
       Get
         Return _reverse
       End Get
       Set(ByVal Value As Boolean)
          _reverse = Value
       End Set
    End Property 
    
    private Boolean reverse;
    [XmlElement("Reverse")]
    public Boolean Reverse 
    {
       get { return reverse; }
       set { reverse = value; }
    }
    

Extension de la génération de description de service et de proxy client

Pour étendre le processus de génération WSDL, dérivez une classe de la classe SoapExtensionReflector. Pour étendre le processus de génération de proxy client, dérivez une classe de la classe SoapExtensionImporter.

Pour étendre le processus de génération de description de service

  1. Créez une classe qui dérive de SoapExtensionReflector.

    L'exemple de code suivant crée la classe TraceReflector qui dérive de SoapExtensionReflector.

    Public Class YMLReflector
        Inherits SoapExtensionReflector
    
    public class YMLReflector : SoapExtensionReflector
    
  2. Remplacez la méthode ReflectMethod, appelée pendant la génération de description de service pour chaque méthode de service Web.

    L'exemple de code suivant remplace la méthode ReflectMethod.

    Public Overrides Sub ReflectMethod()
    
    public override void ReflectMethod()
    
  3. Obtenez la valeur de la propriété ReflectionContext de la classe SoapExtensionReflector pour obtenir une instance de ProtocolReflector.

    L'instance de ProtocolReflector fournit des informations sur le processus de génération WSDL pour la méthode de service Web actuelle. L'exemple de code suivant obtient la valeur de la propriété ReflectionContext.

    Dim reflector As ProtocolReflector = ReflectionContext
    
    ProtocolReflector reflector = ReflectionContext;
    
  4. Ajoutez du code pour remplir la SDFE.

    L'exemple de code suivant ajoute le XML défini par la SDFE à la description de service si le YMLAttribute est appliqué à une méthode de service Web.

    Dim attr As YMLAttribute = _
        reflector.Method.GetCustomAttribute(GetType(YMLAttribute))
    ' If the YMLAttribute has been applied to this Web service
    ' method, adds the XML defined in the YMLOperationBinding class.
    If (Not attr Is Nothing) Then
       Dim yml As YMLOperationBinding = New YMLOperationBinding()
       yml.Reverse = Not attr.Disabled
    
    YMLAttribute attr = (YMLAttribute)
       reflector.Method.GetCustomAttribute(typeof(YMLAttribute));
    // If the YMLAttribute has been applied to this Web service 
    // method, adds the XML defined in the YMLOperationBinding class.
    if (attr != null) {
       YMLOperationBinding yml = new YMLOperationBinding();
       yml.Reverse = !(attr.Disabled);
    
  5. Ajoutez la SDFE à la collection Extensions de la propriété qui représente le point d'extension étendu par la SDFE.

    L'exemple de code suivant ajoute la SDFE YmlOperationBinding au point d'extension OperationBinding.

    reflector.OperationBinding.Extensions.Add(yml)
    
    reflector.OperationBinding.Extensions.Add(yml);
    

Pour étendre le processus de génération de classe proxy

  1. Créez une classe qui dérive de SoapExtensionImporter.

    Public Class YMLImporter
        Inherits SoapExtensionImporter
    
    public class YMLImporter : SoapExtensionImporter
    
  2. Remplacez la méthode ImportMethod.

    Le ImportMethod est appelé pendant la génération de classe proxy pour chaque opération définie dans une description de service. Dans le cas des services Web créés à l'aide d'ASP.NET, chaque méthode de service Web correspond à une opération pour chaque protocole pris en charge dans la description de service.

    Public Overrides Sub ImportMethod(ByVal metadata As _
                                      CodeAttributeDeclarationCollection)
    
    public override void ImportMethod(CodeAttributeDeclarationCollection
                                      metadata)   
    
  3. Obtenez la valeur de la propriété ImportContext de SoapExtensionImporter pour obtenir une instance de SoapProtocolImporter.

    L'instance de SoapProtocolImporter fournit des informations sur le processus de génération de code pour la méthode actuelle qui communique avec une méthode de service Web. L'exemple de code suivant obtient la valeur de la propriété ImportContext.

    Dim importer As SoapProtocolImporter = ImportContext
    
    SoapProtocolImporter importer = ImportContext;  
    
  4. Ajoutez du code pour appliquer ou modifier des attributs pour une méthode dans la classe proxy qui communique avec un service Web.

    Le ImportMethod passe dans un argument de type CodeAttributeDeclarationCollection, qui représente la collection des attributs appliqués à la méthode qui communique avec la méthode de service Web. L'exemple de code suivant ajoute un YMLAttribute à la collection, qui provoque l'exécution de l'extension SOAP YML avec la méthode lorsque la description de service contient le XML approprié.

    ' Checks whether the XML specified in the YMLOperationBinding is in the
    ' service description.
    Dim yml As YMLOperationBinding = _
      importer.OperationBinding.Extensions.Find( _
      GetType(YMLOperationBinding))
    If (Not yml Is Nothing) Then
       ' Only applies the YMLAttribute to the method when the XML should
       ' be reversed.
       If (yml.Reverse) Then
          Dim attr As CodeAttributeDeclaration = New _
            CodeAttributeDeclaration(GetType(YMLAttribute).FullName)
          attr.Arguments.Add(New CodeAttributeArgument(New _
               CodePrimitiveExpression(True)))
          metadata.Add(attr)
       End If
    End If
    
    // Checks whether the XML specified in the YMLOperationBinding is
    // in the service description.
    YMLOperationBinding yml = (YMLOperationBinding)
       importer.OperationBinding.Extensions.Find(
       typeof(YMLOperationBinding));
    if (yml != null)
    {
       // Only applies the YMLAttribute to the method when the XML should
       // be reversed.
       if (yml.Reverse)
       {
         CodeAttributeDeclaration attr = new
            CodeAttributeDeclaration(typeof(YMLAttribute).FullName);
         attr.Arguments.Add(new CodeAttributeArgument(new
            CodePrimitiveExpression(true)));
         metadata.Add(attr);
       }
    }
    

Configuration de la SDFE

Configurer la SDFE requiert des fichiers de configuration d'édition à la fois sur le service Web et le client.

Pour configurer la SDFE pour s'exécuter avec un service Web

  1. Installez l'assembly qui contient la SDFE dans un dossier accessible.

    À moins que la SDFE soit requise pour plusieurs applications Web, installez la SDFE dans le dossier \bin de l'application Web qui héberge le service Web.

  2. Ajoutez un élément <serviceDescriptionFormatExtensionTypes>, élément avec un élément add et spécifiez le nom et l'assembly qui contiennent la SDFE au fichier Web.config pour l'application Web.

    L'exemple de code suivant configure la SDFE Sample.YMLOperationBinding pour qu'elle s'exécute avec tous les services Web affectés par le fichier Web.config. L'élément add complet doit être sur une ligne.

    <system.web>
       <webServices>
          <serviceDescriptionFormatExtensionTypes>
             <add type="Sample.YMLOperationBinding,Yml,
                  Version=1.0.0.0,Culture=neutral,
                  PublicKeyToken=6e55c64c6b897b30"/>
          </serviceDescriptionFormatExtensionTypes>
       </webServices>
    </system.web>
    
  3. Ajoutez un élément <soapExtensionReflectorTypes>, élémentadd avec un élément et spécifiez le nom et l'assembly de la classe qui étend le processus de génération de description de service au fichier Web.config pour l'application Web.

    L'exemple de code suivant configure le Sample.YMLReflector pour s'exécuter avec tous les services Web affectés par le fichier Web.config. L'élément add complet doit figurer sur une ligne.

    <system.web>
       <webServices>
          <serviceDescriptionFormatExtensionTypes>
             <add type="Sample.YMLOperationBinding,Yml,
                  Version=1.0.0.0,Culture=neutral,
                  PublicKeyToken=6e55c64c6b897b30"/>
          </serviceDescriptionFormatExtensionTypes>
          <soapExtensionReflectorTypes>
             <add type="Sample.YMLReflector,Yml,
                  Version=1.0.0.0,Culture=neutral,
                  PublicKeyToken=6e55c64c6b897b30"/>
          </soapExtensionReflectorTypes>
       </webServices>
    </system.web>
    

Pour configurer la SDFE pour s'exécuter avec un client de service Web

  1. Installez l'assembly contenant la SDFE dans le Global Assembly Cache.

    Pour pouvoir être installé, l'assembly doit avoir un nom fort. Pour plus d'informations sur le sujet suivant la création d'un assembly avec nom fort, consultez Création et utilisation d'assemblys avec nom fort. Pour plus d'informations sur le sujet suivant l'installation d'un assembly, consultez Installation d'un assembly dans le Global Assembly Cache.

  2. Ajoutez un élément <serviceDescriptionFormatExtensionTypes>, élémentadd avec un élément et spécifiez le nom et l'assembly qui contiennent la SDFE au fichier Machine.config.

    L'exemple de code suivant configure la SDFE Sample.YMLOperationBinding pour s'exécuter chaque fois que des classes proxy sont générées pour les services Web sur l'ordinateur.

    <system.web>
       <webServices>
          <serviceDescriptionFormatExtensionTypes>
             <add type="Sample.YMLOperationBinding,Yml,
                  Version=1.0.0.0,Culture=neutral,
                  PublicKeyToken=6e55c64c6b897b30"/>
          </serviceDescriptionFormatExtensionTypes>
       </webServices>
    </system.web>
    
  3. Ajoutez un élément <soapExtensionImporterTypes>, élément avec un élément add et spécifiez le nom et l'assembly de la classe qui étend le processus de génération de classe proxy au fichier Machine.config.

    L'exemple de code suivant configure le Sample.YMLImporter pour s'exécuter chaque fois que des classes proxy sont générées pour les services Web sur l'ordinateur.

    <system.web>
       <webServices>
          <serviceDescriptionFormatExtensionTypes>
             <add type="Sample.YMLOperationBinding,Yml,
                  Version=1.0.0.0,Culture=neutral,
                  PublicKeyToken=6e55c64c6b897b30"/>
          </serviceDescriptionFormatExtensionTypes>
          <soapExtensionImporterTypes>
             <add type="Sample.YMLImporter,Yml,
                  Version=1.0.0.0,Culture=neutral,
                  PublicKeyToken=6e55c64c6b897b30"/>
          </soapExtensionImporterTypes>
       </webServices>
    </system.web>
    
    x4s9z3yc.note(fr-fr,VS.100).gifRemarque :
    La méthode générée dans la classe proxy est utilisée par une application cliente qui communique avec le service Web, donc si une SDFE ajoute un attribut résidant dans un assembly non notifié à l'application cliente, une erreur de compilateur est générée. Pour résoudre l'erreur de compilateur, ajoutez une référence à l'assembly contenant l'attribut si vous utilisez Visual Studio .NET, ou ajoutez l'assembly à la ligne de commande du compilateur si vous utilisez la compilation de ligne de commande.

Voir aussi

Tâches

Procédure pas à pas : personnalisation de la génération des descriptions de service et des classes proxy

Référence

XmlFormatExtensionAttribute
XmlFormatExtensionPrefixAttribute
XmlFormatExtensionPointAttribute

Concepts

Modification de messages SOAP à l'aide d'extensions SOAP