Condividi tramite


Procedura dettagliata: personalizzare la generazione delle descrizioni dei servizi e delle classi proxy

Questo argomento è specifico di una tecnologia legacy. Servizi Web XML e client di servizi Web XML devono essere creati attualmente tramite Windows Communication Foundation.

La generazione della descrizione dei servizi e delle classi proxy di un servizio Web creato utilizzando ASP.NET può essere estesa tramite la creazione e l'installazione di un'estensione 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 particolarmente utili quando un'estensione SOAP deve essere eseguita con un servizio Web e con i rispettivi client. Per impostazione predefinita, nessun'informazione sulle estensioni SOAP viene inserita nella descrizione dei servizi o nelle 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 decrittografare il messaggio. Una SDFE può aggiungere elementi alla descrizione del servizio per informare i client che deve essere eseguita un'estensione SOAP e può estendere il processo di generazione di una classe proxy per aggiungere un attributo personalizzato a tale classe per fare in modo che la classe esegua l'estensione SOAP. In questa procedura dettagliata vengono descritte le attività seguenti:

  1. Definizione dell'XML da aggiungere alla descrizione del servizio.

  2. Creazione di una classe SDFE mediante derivazione dalla classe ServiceDescriptionFormatExtension.

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

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

  5. Configurazione della SDFE per l'esecuzione contemporanea nel client e nel server.

Definizione dell'XML e creazione della classe SDFE

Gli esempi di codice di questa procedura dettagliata interessano una classe ServiceDescriptionFormateExtension``YMLOperationBinding per una classe SoapExtension``YMLExtension. Il codice completo è riportato nell'argomento Procedura: personalizzare la generazione delle descrizioni dei servizi e delle classi proxy (codice dell'esempio).

Per 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, l'SDFE dell'esempio dichiara un prefisso dello spazio dei nomi XML yml nell'elemento radice definitions di un documento WSDL e lo applica all'elemento yml:action (e ai rispettivi elementi figlio) riportati 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">OperationBinding alla descrizione del servizio nel punto di estensione . 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 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 alla raccolta 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 la raccolta di attributi applicati al metodo che comunica con il metodo del servizio Web. Nell'esempio di codice seguente viene aggiunto un attributo YMLAttribute alla raccolta 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 l'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 un 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>add all'elemento 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 l'esecuzione con tutti i servizi Web interessati dal file Web.config. È preferibile che l'elemento add completo sia 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 per l'esecuzione con un client del servizio Web

  1. Installare l'assembly che contiene l'SDFE nella Global Assembly Cache

    Per poter essere installato, l'assembly deve essere con nome sicuro. Per ulteriori informazioni su sulla creazione di un assembly con nome sicuro, vedere Creazione e utilizzo degli assembly con nome sicuro. Per ulteriori informazioni su sull'installazione di un assembly, vedere Installazione di un assembly nella Global Assembly Cache.

  2. Aggiungere l'elemento Elemento <serviceDescriptionFormatExtensionTypes>add all'elemento 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>
    
    x4s9z3yc.note(it-it,VS.100).gifNota:
    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: personalizzare la generazione delle descrizioni dei servizi e delle classi proxy

Riferimento

XmlFormatExtensionAttribute
XmlFormatExtensionPrefixAttribute
XmlFormatExtensionPointAttribute

Concetti

Modifica di messaggi SOAP utilizzando estensioni SOAP