Condividi tramite


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:

  1. Definire l'XML da aggiungere alla descrizione del servizio.

  2. Creare una classe SDFE derivando dalla classe ServiceDescriptionFormatExtension.

  3. Scrivere codice per estendere il processo di generazione delle descrizioni dei servizi.

  4. Scrivere codice per estendere il processo di generazione delle classi proxy.

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

  1. 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'elemento yml: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>
    
  2. 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
    
  3. 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 SDFEYMLOperationBinding 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 XML https://www.contoso.com/yml viene specificato in un secondo momento quando il campo YMLOperationBinding.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
    
  4. 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 XMLyml è associato allo spazio dei nomi https://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 
    
  5. 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

  1. 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
    
  2. 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()
    
  3. 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;
    
  4. 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);
    
  5. 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

  1. Creare una classe che deriva da SoapExtensionImporter.

    Public Class YMLImporter
        Inherits SoapExtensionImporter
    
    public class YMLImporter : SoapExtensionImporter
    
  2. 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)   
    
  3. 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;  
    
  4. 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 attributoYMLAttribute all'insieme che fa in modo che l'estensione SOAP YML 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

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

  2. 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>
    
  3. 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 seguenteSample.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

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

  2. 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>
    
  3. 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>
    
    NoteNota:

    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à

Procedura dettagliata: Personalizzazione della generazione delle descrizioni dei servizi e delle classi proxy

Riferimenti

XmlFormatExtensionAttribute
XmlFormatExtensionPrefixAttribute
XmlFormatExtensionPointAttribute

Concetti

Modifica di messaggi SOAP utilizzando estensioni SOAP

Footer image

Copyright © 2007 Microsoft Corporation. Tutti i diritti riservati.