Exemplarische Vorgehensweise: Anpassen der Generierung von Dienstbeschreibungen und Proxyklassen.

Dieses Thema bezieht sich auf eine veraltete Technologie. XML-Webdienste und XML-Webdienstclients sollten nun mithilfe der folgenden Technologie erstellt werden: Windows Communication Foundation.

Die Generierung der Dienstbeschreibung und der Proxyklassen eines mit ASP.NET erstellten Webdiensts kann durch das Erstellen und Installieren einer Dienstbeschreibungsformaterweiterung (SDFE, Service Description Format Extension) erweitert werden. Insbesondere können mit der SDFE zur Dienstbeschreibung, d. h. dem WSDL-Dokument (Web Services Description Language) für einen Webdienst, XML-Elemente hinzugefügt und einer Methode, die mit einem Webdienst kommuniziert, benutzerdefinierte Attribute hinzugefügt werden.

SDFEs bieten sich besonders an, wenn eine SOAP-Erweiterung sowohl mit einem Webdienst als auch mit dessen Clients ausgeführt werden soll. In der Standardeinstellung werden keine Informationen über SOAP-Erweiterungen in der Dienstbeschreibung oder in den hierfür generierten Proxyklassen platziert. Ein Beispiel für eine SOAP-Erweiterung, die sowohl auf dem Client als auch auf dem Server ausgeführt werden muss, ist eine SOAP-Verschlüsselungserweiterung. Wenn eine SOAP-Verschlüsselungserweiterung auf dem Server ausgeführt wird und SOAP-Antworten verschlüsselt, muss die SOAP-Erweiterung zum Entschlüsseln der SOAP-Nachricht auf dem Client ausgeführt werden. Eine SDFE kann der Dienstbeschreibung Elemente hinzufügen, um Clients zu informieren, dass eine SOAP-Erweiterung ausgeführt werden muss. Außerdem kann die SDFE den Generierungsprozess der Proxyklasse erweitern, um der Proxyklasse ein benutzerdefiniertes Attribut hinzuzufügen, sodass die SOAP-Erweiterung von der Klasse ausgeführt wird. Diese exemplarische Vorgehensweise demonstriert die folgenden Aufgaben:

  1. Definieren des XML-Codes, der der Dienstbeschreibung hinzugefügt werden soll

  2. Erstellen einer SDFE-Klasse durch Ableiten von der ServiceDescriptionFormatExtension-Klasse

  3. Schreiben von Code zum Erweitern des Generierungsprozesses der Dienstbeschreibung

  4. Schreiben von Code zum Erweitern des Generierungsprozesses der Proxyklasse

  5. Konfigurieren der SDFE für die Ausführung auf Client und Server

Definieren des XML-Codes und Erstellen der SDFE-Klasse

In den Codebeispielen in dieser exemplarischen Vorgehensweise ist eine ServiceDescriptionFormateExtension-Klasse YMLOperationBinding für eine SoapExtension-Klasse YMLExtension enthalten. Der vollständige Code wird im Thema Vorgehensweise: Anpassen der Generierung von Dienstbeschreibungen und Proxyklassen (Beispielcode) angezeigt.

So definieren Sie den XML-Code, der der Dienstbeschreibung hinzugefügt werden muss

  1. Entscheiden Sie, welcher XML-Code der Dienstbeschreibung hinzugefügt werden muss

    Im folgenden Codebeispiel wird der Teil einer Dienstbeschreibung dargestellt, dem XML-Elemente durch die Beispiel-SDFE hinzugefügt werden. Im Beispiel-SDFE wird ein XML-Namespacepräfix yml im definitions-Stammelement des WSDL-Dokuments deklariert, und dann wird dieser Namespace auf das yml:action-Element (und untergeordnete Elemente) angewendet, die in operation-Elementen enthalten sind.

    <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. Erstellen Sie eine von ServiceDescriptionFormatExtension abgeleitete Klasse.

    Wenn Sie mit Visual Studio .NET arbeiten, fügen Sie einen Verweis auf die System.Web.Services-Assembly hinzu. Fügen Sie der Datei außerdem eine using-Anweisung oder Imports-Anweisung für den System.Web.Services.Description-Namespace hinzu.

    Im folgenden Codebeispiel wird die Klasse YMLOperationBinding erstellt, die von der ServiceDescriptionFormatExtension-Klasse abgeleitet ist.

    Public Class YMLOperationBinding
        Inherits ServiceDescriptionFormatExtension
    
    public class YMLOperationBinding : ServiceDescriptionFormatExtension
    
  3. Wenden Sie ein XmlFormatExtensionAttribute auf die Klasse an.

    Dieses Attribut gibt die Phase des Generierungsprozesses für die Dienstbeschreibung an, die als der Erweiterungspunkt bezeichnet und in der die SDFE ausgeführt wird. In der folgenden Tabelle werden die definierten Erweiterungspunkte und die während jedes Punktes generierten WSDL-XML-Elemente aufgelistet. Für den angegebenen Erweiterungspunkt wird das entsprechende WSDL-Element zum übergeordneten Element des hinzugefügten Elements.

    Erweiterungspunkt Beschreibung

    ServiceDescription

    Entspricht dem definitions-Stammelement eines WSDL-Dokuments.

    Types

    Entspricht dem types-Element, das im definitions-Element enthalten ist.

    Binding

    Entspricht dem binding-Element, das im definitions-Element enthalten ist.

    OperationBinding

    Entspricht dem operation-Element, das im binding-Element enthalten ist.

    InputBinding

    Entspricht dem input-Element, das im operation-Element enthalten ist.

    OutputBinding

    Entspricht dem output-Element, das im operation-Element enthalten ist.

    FaultBinding

    Entspricht dem fault-Element, das im operation-Element enthalten ist.

    Port

    Entspricht dem port-Element, das im service-Element enthalten ist.

    Operation

    Entspricht dem operation-Element, das im portType-Element enthalten ist.

    Wenn Sie ein XmlFormatExtensionAttribute auf die Klasse anwenden, geben Sie auch den XML-Elementnamen und den XML-Namespace an, der die der Dienstbeschreibung hinzuzufügenden XML-Elemente enthalten soll.

    Im folgenden Codebeispiel wird angegeben, dass die YMLOperationBinding SDFE der Dienstbeschreibung ein XML-Element namens <action xmlns="https://www.contoso.com/yml">OperationBinding im -Erweiterungspunkt hinzufügt. In diesem Beispiel wird der XML-Namespace https://www.contoso.com/yml später angegeben, wenn das YMLOperationBinding.YMLNamespace-Feld der Klasse hinzugefügt wird.

    <XmlFormatExtension("action", YMLOperationBinding.YMLNamespace, _
                        GetType(OperationBinding))> _
    Public Class YMLOperationBinding
        Inherits ServiceDescriptionFormatExtension
    
    [XmlFormatExtension("action", YMLOperationBinding.YMLNamespace,
                        typeof(OperationBinding))]
    public class YMLOperationBinding : ServiceDescriptionFormatExtension
    
  4. Optional können Sie ein XmlFormatExtensionPrefixAttribute auf die Klasse anwenden, um das XML-Namespacepräfix dem von der SDFE verwendeten Namespace zuzuordnen.

    Im folgenden Codebeispiel wird angegeben, dass das XML-Namespacepräfix yml zum Namespace https://www.contoso.com/yml im definitions-Element der Dienstbeschreibung hinzugefügt wird. Außerdem wird bei Elementen, die von der SDFE hinzugefügt werden, anstelle des Namespace das Präfix verwendet. Für das der Dienstbeschreibung in Schritt 3 hinzugefügte XML-Element wird nun das Namespacepräfix verwendet, und daher lautet das hinzugefügte Element <yml:action> statt <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. Fügen Sie öffentliche Eigenschaften und Felder zu der Klasse hinzu, die den zum WSDL-Dokument hinzuzufügenden XML-Code darstellt. Im folgenden Codebeispiel wird eine öffentliche Reverse-Eigenschaft hinzugefügt, die in ein <yml:Reverse>value</yml:Reverse>-Element im WSDL-Dokument serialisiert wird.

    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; }
    }
    

Erweitern der Generierung der Dienstbeschreibung und des Clientproxys

Zum Erweitern des WSDL-Generierungsprozesses leiten Sie eine Klasse von der SoapExtensionReflector-Klasse ab. Zum Erweitern des Clientproxy-Generierungsprozesses leiten Sie eine Klasse von der SoapExtensionImporter-Klasse ab.

So erweitern Sie den Generierungsprozess der Dienstbeschreibung

  1. Erstellen Sie eine Klasse, die von SoapExtensionReflector abgeleitet ist.

    Im folgenden Codebeispiel wird die Klasse TraceReflector erstellt, die von der SoapExtensionReflector-Klasse abgeleitet ist.

    Public Class YMLReflector
        Inherits SoapExtensionReflector
    
    public class YMLReflector : SoapExtensionReflector
    
  2. Überschreiben Sie die ReflectMethod-Methode, die während der Generierung der Dienstbeschreibung für jede Webdienstmethode aufgerufen wird.

    Im folgenden Codebeispiel wird die ReflectMethod-Methode überschrieben.

    Public Overrides Sub ReflectMethod()
    
    public override void ReflectMethod()
    
  3. Rufen Sie den Wert der ReflectionContext-Eigenschaft der SoapExtensionReflector-Klasse ab, um eine Instanz von ProtocolReflector abzurufen.

    Die Instanz von ProtocolReflector stellt Details über den WSDL-Generierungsprozess für die aktuelle Webdienstmethode bereit. Im folgenden Codebeispiel wird der Wert der ReflectionContext-Eigenschaft abgerufen.

    Dim reflector As ProtocolReflector = ReflectionContext
    
    ProtocolReflector reflector = ReflectionContext;
    
  4. Fügen Sie Code hinzu, mit dem die SDFE mit Daten gefüllt wird.

    Im folgenden Codebeispiel wird zur Dienstbeschreibung der von der SDFE definierte XML-Code hinzugefügt, wenn YMLAttribute auf eine Webdienstmethode angewendet wird.

    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. Fügen Sie die SDFE der Extensions-Auflistung der Eigenschaft hinzu, die den durch die SDFE erweiterten Erweiterungspunkt darstellt.

    Im folgenden Codebeispiel wird die SDFE YmlOperationBinding dem OperationBinding-Erweiterungspunkt hinzugefügt.

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

So erweitern Sie den Generierungsprozess der Proxyklasse

  1. Erstellen Sie eine Klasse, die von SoapExtensionImporter abgeleitet ist.

    Public Class YMLImporter
        Inherits SoapExtensionImporter
    
    public class YMLImporter : SoapExtensionImporter
    
  2. Überschreiben Sie die ImportMethod-Methode.

    Die ImportMethod-Methode wird während der Proxyklassengenerierung für jeden in einer Dienstbeschreibung definierten Vorgang aufgerufen. Bei mit ASP.NET erstellten Webdiensten wird jede Webdienstmethode für jedes in der Dienstbeschreibung unterstützte Protokoll einem Vorgang zugeordnet.

    Public Overrides Sub ImportMethod(ByVal metadata As _
                                      CodeAttributeDeclarationCollection)
    
    public override void ImportMethod(CodeAttributeDeclarationCollection
                                      metadata)   
    
  3. Rufen Sie den Wert der ImportContext-Eigenschaft der SoapExtensionImporter-Klasse ab, um eine Instanz von SoapProtocolImporter abzurufen.

    Die Instanz von SoapProtocolImporter stellt Details über den Codegenerierungsprozess für die aktuelle Methode bereit, die mit einer Webdienstmethode kommuniziert. Im folgenden Codebeispiel wird der Wert der ImportContext-Eigenschaft abgerufen.

    Dim importer As SoapProtocolImporter = ImportContext
    
    SoapProtocolImporter importer = ImportContext;  
    
  4. Fügen Sie Code hinzu, um Attribute auf eine Methode der Proxyklasse anzuwenden, die mit einem Webdienst kommuniziert, oder einer solchen Methode Attribute hinzuzufügen.

    Die ImportMethod-Methode übergibt ein Argument des Typs CodeAttributeDeclarationCollection, das eine Auflistung von Attributen darstellt, die auf die mit der Webdienstmethode kommunizierende Methode angewendet werden. Im folgenden Codebeispiel wird der Auflistung ein YMLAttribute hinzugefügt. Dadurch wird die SOAP-Erweiterung YML mit der Methode ausgeführt, wenn die Dienstbeschreibung den entsprechenden XML-Code enthält.

    ' 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);
       }
    }
    

Konfigurieren der SDFE

Zum Konfigurieren der SDFE müssen Sie Konfigurationsdateien für den Webdienst und den Client bearbeiten.

So konfigurieren Sie die SDFE-Erweiterung für die Ausführung mit einem Webdienst

  1. Installieren Sie die Assembly mit der SDFE in einem Ordner, der zugänglich ist.

    Sofern die SDFE nicht für mehrere Webanwendungen benötigt wird, installieren Sie die SDFE im Ordner \bin der Webanwendung, die als Host des Webdiensts fungiert.

  2. Fügen Sie der Datei "Web.config" für die Webanwendung ein <serviceDescriptionFormatExtensionTypes>-Element-Element mit einem add-Element hinzu, und geben Sie den Namen und die Assembly an, die die SDFE enthält.

    Im folgenden Codebeispiel wird die SDFE Sample.YMLOperationBinding für die Ausführung mit allen Webdiensten konfiguriert, auf die sich die Datei Web.config auswirkt. Das gesamte add-Element sollte in einer Zeile stehen.

    <system.web>
       <webServices>
          <serviceDescriptionFormatExtensionTypes>
             <add type="Sample.YMLOperationBinding,Yml,
                  Version=1.0.0.0,Culture=neutral,
                  PublicKeyToken=6e55c64c6b897b30"/>
          </serviceDescriptionFormatExtensionTypes>
       </webServices>
    </system.web>
    
  3. Fügen Sie der Datei Web.config für die Webanwendung ein <soapExtensionReflectorTypes>-Elementadd-Element mit einem -Element hinzu, und geben Sie den Namen und die Assembly der Klasse an, die den Generierungsprozess der Dienstbeschreibung erweitert.

    Im folgenden Codebeispiel wird Sample.YMLReflector für die Ausführung mit allen Webdiensten konfiguriert, auf die sich die Datei "Web.config" auswirkt. Das gesamte add-Element sollte in einer Zeile stehen.

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

So konfigurieren Sie die SDFE für die Ausführung mit einem Webdienstclient

  1. Installieren Sie die Assembly mit der SDFE im globalen Assemblycache.

    Die Assembly muss über einen starken Namen verfügen, um installiert werden zu können. Weitere Informationen über Erstellen einer Assembly mit starkem Namen finden Sie unter Erstellen und Verwenden von Assemblys mit starkem Namen. Weitere Informationen über Installieren einer Assembly finden Sie unter Installieren einer Assembly in den globalen Assemblycache.

  2. Fügen Sie der Datei Machine.config ein <serviceDescriptionFormatExtensionTypes>-Elementadd-Element mit einem -Element hinzu, und geben Sie den Namen und die Assembly an, die die SDFE enthält.

    Im folgenden Codebeispiel wird die SDFE Sample.YMLOperationBinding so konfiguriert, dass sie immer dann ausgeführt wird, wenn Proxyklassen für Webdienste auf dem Computer generiert werden.

    <system.web>
       <webServices>
          <serviceDescriptionFormatExtensionTypes>
             <add type="Sample.YMLOperationBinding,Yml,
                  Version=1.0.0.0,Culture=neutral,
                  PublicKeyToken=6e55c64c6b897b30"/>
          </serviceDescriptionFormatExtensionTypes>
       </webServices>
    </system.web>
    
  3. Fügen Sie der Datei Web.config ein <soapExtensionImporterTypes>-Element-Element mit einem add-Element hinzu, und geben Sie den Namen und die Assembly der Klasse an, die den Generierungsprozess der Proxyklasse erweitert.

    Im folgenden Codebeispiel wird die SDFE Sample.YMLImporter so konfiguriert, dass sie immer dann ausgeführt wird, wenn Proxyklassen für Webdienste auf dem Computer generiert werden.

    <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(de-de,VS.100).gifHinweis:
    Die in der Proxyklasse generierte Methode wird von einer Clientanwendung verwendet, die mit dem Webdienst kommuniziert. Wenn daher eine SDFE ein Attribut hinzufügt, das in einer der Clientanwendung unbekannten Assembly enthalten ist, wird ein Compilerfehler generiert. Um den Compilerfehler zu beheben, fügen Sie bei Verwendung von Visual Studio .NET der Assembly, die das Attribut enthält, einen Verweis hinzu, oder fügen Sie die Assembly der Compilerbefehlszeile hinzu, wenn Sie den Befehlszeilencompiler verwenden.

Siehe auch

Aufgaben

Exemplarische Vorgehensweise: Anpassen der Generierung von Dienstbeschreibungen und Proxyklassen.

Verweis

XmlFormatExtensionAttribute
XmlFormatExtensionPrefixAttribute
XmlFormatExtensionPointAttribute

Konzepte

SOAP-Nachrichtenänderung mit SOAP-Erweiterungen