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:
Definieren des XML-Codes, der der Dienstbeschreibung hinzugefügt werden soll
Erstellen einer SDFE-Klasse durch Ableiten von der ServiceDescriptionFormatExtension-Klasse
Schreiben von Code zum Erweitern des Generierungsprozesses der Dienstbeschreibung
Schreiben von Code zum Erweitern des Generierungsprozesses der Proxyklasse
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
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 dasyml: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>
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
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-Namespacehttps://www.contoso.com/yml
später angegeben, wenn dasYMLOperationBinding.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
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 Namespacehttps://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
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
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
Ü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()
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;
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);
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
Erstellen Sie eine Klasse, die von SoapExtensionImporter abgeleitet ist.
Public Class YMLImporter Inherits SoapExtensionImporter
public class YMLImporter : SoapExtensionImporter
Ü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)
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;
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-ErweiterungYML
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
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.
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>
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
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.
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>
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>
Hinweis: 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