Procédure pas à pas : personnalisation de la génération des descriptions de service et des classes proxy
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. Au cours de cette procédure pas à pas, vous apprenez à :
Définir le XML à ajouter à la description de service.
Créer une classe SDFE en dérivant de la classe ServiceDescriptionFormatExtension.
Écrire le code pour étendre le processus de génération de description du service.
Écrire le code pour étendre le processus de génération de classe proxy.
Configurer 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 un YMLOperationBinding de classe ServiceDescriptionFormateExtension pour un YMLExtension de classe SoapExtension. Le code complet est indiqué 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
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émentyml: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>
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
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">
à la description de service pendant le point d'extension OperationBinding. Pour cet exemple, l'espace de nomshttps://www.contoso.com/yml
XML est spécifié ultérieurement lorsque le champYMLOperationBinding.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
É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 nomshttps://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
Ajoutez des propriétés et/ou 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
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
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()
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;
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);
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
Créez une classe qui dérive de SoapExtensionImporter.
Public Class YMLImporter Inherits SoapExtensionImporter
public class YMLImporter : SoapExtensionImporter
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)
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;
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 SOAPYML
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
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.
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>
Ajoutez un élément <soapExtensionReflectorTypes>, é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 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 être 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
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 la création d'un assembly avec nom fort, consultez Création et utilisation d'assemblys avec nom fort. Pour plus d'informations sur l'installation d'un assembly, consultez Installation d'un assembly dans le Global Assembly Cache.
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 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>
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>
Remarque :
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
Référence
XmlFormatExtensionAttribute
XmlFormatExtensionPrefixAttribute
XmlFormatExtensionPointAttribute
Concepts
Modification de messages SOAP à l'aide d'extensions SOAP
Copyright ©2007 par Microsoft Corporation. Tous droits réservés.