Procedura dettagliata: Personalizzazione della generazione delle descrizioni dei servizi e delle classi proxy
La generazione delle descrizioni dei servizi e delle classi proxy di un servizio Web creato utilizzando ASP.NET può essere estesa tramite la creazione e l'installazione di estensioni di formato di descrizione servizio (SDFE). In particolare, una SDFE può aggiungere elementi XML alla descrizione del servizio, il documento WSDL (Web Services Description Language) di un servizio Web, e aggiungere attributi personalizzati a un metodo che comunica con un servizio Web.
Le SDFE sono utili specialmente quando un'estensione SOAP deve essere in esecuzione con un servizio Web e i client; per impostazione predefinita, nessun'informazione sulle estensioni SOAP viene posizionata nelle descrizioni dei servizi o delle classi proxy per essi generate. Un esempio di estensione SOAP la cui esecuzione è necessaria sia sul client che sul server è costituito da un'estensione SOAP di crittografia. Se un'estensione SOAP di crittografia viene eseguita sul server per crittografare la risposta SOAP, il client deve avere l'estensione SOAP in esecuzione per decifrare il messaggio. Una SDFE può aggiungere elementi alla descrizione del servizio per informare un client che un'estensione SOAP deve essere in esecuzione e può estendere il processo di generazione di una classe proxy per aggiungere un attributo personalizzato a essa per fare in modo che la classe esegua l'estensione SOAP. In particolare, vengono illustrate le seguenti operazioni:
Definire l'XML da aggiungere alla descrizione del servizio.
Creare una classe SDFE derivando dalla classe ServiceDescriptionFormatExtension.
Scrivere codice per estendere il processo di generazione delle descrizioni dei servizi.
Scrivere codice per estendere il processo di generazione delle classi proxy.
Configurare la SDFE per l'esecuzione contemporanea nel client e nel server.
Definire l'XML e creare la classe SDFE
Gli esempi di codice in questa procedura dettagliata comportano una classe ServiceDescriptionFormateExtension YMLOperationBinding per una classe SoapExtension YMLExtension. Il codice completo viene visualizzato nell'argomento Procedura: Personalizzare la generazione delle descrizioni dei servizi e delle classi proxy (esempio di codice).
Definire l'XML da aggiungere alla descrizione del servizio
Decidere l'XML da aggiungere alla descrizione del servizio.
L'esempio di codice seguente fa parte di una descrizione del servizio in cui SDFE aggiunge elementi XML. In particolare, SDFE dichiara un spazio dei nomi XML prefisso
yml
nell'elemento radice definitions di un documento WSDL e lo applica all'elementoyml:action
(e agli elementi figlio) che viene visualizzato nell'associazione di elementi 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>
Creare una classe che deriva da ServiceDescriptionFormatExtension.
Quando si utilizza Visual Studio .NET, aggiungere un riferimento all'assembly System.Web.Services . Aggiungere al file anche un'istruzione using o Imports per lo spazio dei nomi System.Web.Services.Description.
Nell'esempio di codice riportato di seguito viene creata una classe denominata
YMLOperationBinding
, che deriva dalla classe ServiceDescriptionFormatExtension .Public Class YMLOperationBinding Inherits ServiceDescriptionFormatExtension
public class YMLOperationBinding : ServiceDescriptionFormatExtension
Applicare un XmlFormatExtensionAttribute alla classe.
Questo attributo specifica la fase del processo di generazione delle descrizioni dei servizi, noto come punto di estensione in cui SDFE viene eseguita. La tabella seguente elenca i punti di estensione definiti e gli elementi XML WSDL generati in ogni punto. Per un punto di estensione specificato, l'elemento WSDL corrispondente diviene il padre dell'elemento aggiunto.
Punto di estensione Descrizione ServiceDescription
Corrisponde all'elemento radice definitions di un documento WSDL.
Types
Corrisponde all'elemento types racchiuso dall'elemento radice definitions.
Binding
Corrisponde all'elemento binding racchiuso dall'elemento radice definitions.
OperationBinding
Corrisponde all'elemento operation racchiuso dall'elemento binding.
InputBinding
Corrisponde all'elemento input racchiuso dall'elemento operation.
OutputBinding
Corrisponde all'elemento output racchiuso dall'elemento operation.
FaultBinding
Corrisponde all'elemento fault racchiuso dall'elemento operation.
Port
Corrisponde all'elemento port racchiuso dall'elemento service.
Operation
Corrisponde all'elemento operation racchiuso dall'elemento portType.
Quando si applica una classe XmlFormatExtensionAttribute alla classe, si specifica anche il nome dell'elemento XML e lo spazio dei nomi XML per contenere gli elementi XML da aggiungere alla descrizione del servizio.
L'esempio di codice seguente specifica che SDFE
YMLOperationBinding
aggiunge un elemento XML denominato<action xmlns="https://www.contoso.com/yml">
alla descrizione del servizio nel punto di estensione OperationBinding. Per questo esempio, lo spazio dei nomi XMLhttps://www.contoso.com/yml
viene specificato in un secondo momento quando il campoYMLOperationBinding.YMLNamespace
viene aggiunto alla classe.<XmlFormatExtension("action", YMLOperationBinding.YMLNamespace, _ GetType(OperationBinding))> _ Public Class YMLOperationBinding Inherits ServiceDescriptionFormatExtension
[XmlFormatExtension("action", YMLOperationBinding.YMLNamespace, typeof(OperationBinding))] public class YMLOperationBinding : ServiceDescriptionFormatExtension
Facoltativamente, applicare un XmlFormatExtensionPrefixAttribute alla classe per associare lo spazio dei nomi XML prefisso allo spazio dei nomi XML utilizzato da SDFE.
L'esempio di codice seguente specifica che il prefisso dello spazio dei nomi XML
yml
è associato allo spazio dei nomihttps://www.contoso.com/yml
nell'elemento definitions della descrizione del servizio. Inoltre, il prefisso viene utilizzato in elementi aggiunti da SDFE al posto dello spazio dei nomi. Pertanto, l'elemento XML aggiunto alla descrizione del servizio nel passaggio 3 ora utilizza il prefisso dello spazio dei nomi e quindi l'elemento aggiunto è<yml:action>
anziché<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
Aggiungere proprietà pubbliche e/o campi alla classe che rappresenta l'XML da aggiungere al documento WSDL. Nell'esempio di codice seguente viene aggiunta una proprietà pubblica
Reverse
serializzata in un elemento<yml:Reverse>value</yml:Reverse>
in 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; } }
Estensione della generazione delle descrizioni dei servizi e dei proxy client
Per estendere il processo di generazione WSDL, occorre derivare una classe dalla classe SoapExtensionReflector. Per estendere il processo di generazione proxy client, occorre derivare una classe dalla classe SoapExtensionImporter.
Per estendere il processo di generazione delle descrizioni dei servizi
Creare una classe che deriva da SoapExtensionReflector.
Nell'esempio di codice riportato di seguito viene creata una classe denominata
TraceReflector
, che deriva dalla classe SoapExtensionReflector .Public Class YMLReflector Inherits SoapExtensionReflector
public class YMLReflector : SoapExtensionReflector
Eseguire l'override del metodo ReflectMethod, richiesto durante la generazione della descrizione del servizio per ogni metodo del servizio Web.
Nell'esempio di codice riportato di seguito viene eseguito l'ovverride del metodo ReflectMethod.
Public Overrides Sub ReflectMethod()
public override void ReflectMethod()
Ottenere il valore della proprietà ReflectionContext della classe SoapExtensionReflector per ottenere un'istanza di ProtocolReflector.
L'istanza della classe ProtocolReflector fornisce dettagli sul processo di generazione WSDL per il metodo corrente del servizio Web. Nell'esempio di codice riportato di seguito viene ottenuto il valore della proprietà ReflectionContext.
Dim reflector As ProtocolReflector = ReflectionContext
ProtocolReflector reflector = ReflectionContext;
Aggiungere il codice per compilare la SDFE.
Nell'esempio di codice seguente viene aggiunto l'XML definito da SDFE alla descrizione del servizio se
YMLAttribute
viene applicato a un metodo del servizio 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);
Aggiungere l'SDFE all'insieme Extensions della proprietà che rappresenta il punto di estensione che l'SDFE sta estendendo.
Nell'esempio di codice riportato di seguito viene illustrato come aggiungere l'SDEF
YmlOperationBinding
al punto di estensione OperationBinding.reflector.OperationBinding.Extensions.Add(yml)
reflector.OperationBinding.Extensions.Add(yml);
Per scrivere codice per estendere il processo di generazione delle classi proxy
Creare una classe che deriva da SoapExtensionImporter.
Public Class YMLImporter Inherits SoapExtensionImporter
public class YMLImporter : SoapExtensionImporter
Eseguire l'override del metodo ImportMethod.
ImportMethod è richiesto durante la generazione della classe proxy per ogni operazione definita in una descrizione del servizio. Per i servizi Web creati con ASP.NET, ogni metodo di servizio Web esegue il mapping su un'operazione per ogni protocollo supportato nella descrizione del servizio.
Public Overrides Sub ImportMethod(ByVal metadata As _ CodeAttributeDeclarationCollection)
public override void ImportMethod(CodeAttributeDeclarationCollection metadata)
Ottenere il valore della proprietà ImportContext della classe SoapExtensionImporter per ottenere un'istanza di SoapProtocolImporter.
L'istanza della classe SoapProtocolImporter fornisce dettagli sul processo di generazione di codice per il metodo corrente che comunica con un servizio Web. Nell'esempio di codice riportato di seguito viene ottenuto il valore della proprietà ImportContext.
Dim importer As SoapProtocolImporter = ImportContext
SoapProtocolImporter importer = ImportContext;
Aggiungere codice per applicare o modificare attributi di un metodo nella classe proxy che sta comunicando con un servizio Web.
ImportMethod passa in un argomento di tipo CodeAttributeDeclarationCollectionche rappresenta l'insieme di attributi applicato al metodo che comunica con il metodo di servizio Web. Nell'esempio di codice seguente viene aggiunto un attributo
YMLAttribute
all'insieme che fa in modo che l'estensione SOAPYML
sia in esecuzione con il metodo quando la descrizione del servizio contiene XML adatto.' 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); } }
Configurazione di SDFE
Configurare SDFE richiede la modifica dei file di configurazione sul servizio Web e sul client.
Per configurare l'SDFE di modo che sia in esecuzione con un servizio Web
Installare l'assembly che contiene l'SDFE in una cartella accessibile.
A meno che SDFE non sia richiesta per più applicazioni Web, installarla nella cartella \Bin dell'applicazione Web che ospita il servizio Web.
Aggiungere l'elemento Elemento <serviceDescriptionFormatExtensionTypes> con l'elemento add e specificare il nome e l'assembly che contengono l'SDFE al file Web.config per l'applicazione Web.
Nell'esempio di codice seguente SDFE viene configurata
Sample.YMLOperationBinding
per essere in esecuzione con tutti i servizi Web interessati dal file Web.config. L'elemento add completo deve essere su una sola riga.<system.web> <webServices> <serviceDescriptionFormatExtensionTypes> <add type="Sample.YMLOperationBinding,Yml, Version=1.0.0.0,Culture=neutral, PublicKeyToken=6e55c64c6b897b30"/> </serviceDescriptionFormatExtensionTypes> </webServices> </system.web>
Aggiungere l'elemento Elemento <soapExtensionReflectorTypes> all'elemento add e specificare il nome e l'assembly della classe che estende il processo della descrizione della generazione dei servizi al file Web.config per l'applicazione Web.
Nell'esempio di codice seguente
Sample.YMLReflector
viene configurata per essere in esecuzione con tutti i servizi Web interessati dal file Web.config. L'elemento add completo deve essere su una sola riga.<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>
Per configurare l'SDFE di modo che sia in esecuzione con un client servizio Web
Installare l'assembly che contiene l'SDFE nella Global Assembly Cache
Affinché l'installazione abbia successo, è necessario che l'assembly disponga di un nome sicuro. Per ulteriori informazioni sulla creazione di un assembly con nome sicuro, vedere Creazione e utilizzo degli assembly con nome sicuro. Per ulteriori informazioni sull'installazione degli assembly, vedere Installazione di un assembly nella Global Assembly Cache.
Aggiungere l'elemento Elemento <serviceDescriptionFormatExtensionTypes> all'elemento add e specificare il nome e l'assembly che contiene l'SDFE sul file Machine.config.
Nell'esempio di codice seguente la SDFE viene configurata
Sample.YMLOperationBinding
per essere eseguita ogni qualvolta vengono generate classi proxy per i servizi Web presenti sul computer.<system.web> <webServices> <serviceDescriptionFormatExtensionTypes> <add type="Sample.YMLOperationBinding,Yml, Version=1.0.0.0,Culture=neutral, PublicKeyToken=6e55c64c6b897b30"/> </serviceDescriptionFormatExtensionTypes> </webServices> </system.web>
Aggiungere l'elemento Elemento <soapExtensionImporterTypes> all'elemento add e specificare il nome e l'assembly della classe che estende il processo della descrizione della generazione della clsse proxy sul file Machine.config.
Nell'esempio di codice seguente
Sample.YMLImporter
viene configurato per essere eseguito ogni qualvolta vengono generate classi proxy per i servizi Web presenti sul computer.<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>
Nota: Il metodo generato nella classe proxy viene utilizzato da un'applicazione client che comunica con il servizio Web, pertanto se una SDFE aggiunge un attributo che risiede in un assembly dal quale l'applicazione client non riceve una notifica, viene generato un errore di compilazione. Per risolvere l'errore di compilazione, aggiungere un riferimento all'assembly che contiene l'attributo in caso si utilizzi Visual Studio .NET, o aggiungere l'assembly alla riga di comando del compilatore, in caso di compilazione da riga di comando.
Vedere anche
Attività
Riferimenti
XmlFormatExtensionAttribute
XmlFormatExtensionPrefixAttribute
XmlFormatExtensionPointAttribute
Concetti
Modifica di messaggi SOAP utilizzando estensioni SOAP
Copyright © 2007 Microsoft Corporation. Tutti i diritti riservati.