SOAP-Nachrichtenänderung mit SOAP-Erweiterungen
Mit SOAP-Erweiterungen können Entwickler die Funktionalität eines Webdiensts vergrößern, indem sie die SOAP-Nachrichten ändern, die an einen und von einem Webdienst oder Webdienstclient gesendet wurden. Sie können zum Beispiel einen Verschlüsselungs- oder einen Komprimierungsalgorithmus implementieren, der mit einem vorhandenen Webdienst ausgeführt werden soll.
Um die Funktionsweise einer SOAP-Erweiterung zu verstehen, müssen Sie zunächst die Lebensdauer eines Webdiensts verstehen. Weitere Informationen finden Sie unter Aufbau der Lebensdauer von XML-Webdiensten.
Die folgende Abbildung gibt einen groben Überblick über die Hauptphasen eines Aufrufs von einem Client zu einem Webdienst.
Aufbau einer Webdienstlebensdauer
Wie Sie sehen, serialisiert und deserialisiert .NET Framework XML phasenweise sowohl auf dem Webdienstcomputer als auch auf dem Computer des Webdienstclients. Eine SOAP-Erweiterung kann in die Infrastruktur eingefügt werden, um die SOAP-Nachrichten vor und nach jeder dieser Serialisierungs- und Deserialisierungsphasen zu überprüfen oder zu ändern. So könnte beispielsweise eine Verschlüsselungs-SOAP-Erweiterung den XML-Teil der SOAP-Nachricht verschlüsseln, nachdem .NET Framework die Argumente des Clients serialisiert hat, und die SOAP-Nachricht anschließend auf dem Webserver entschlüsseln, bevor .NET Framework die SOAP-Nachricht deserialisiert. Diese Phasen, in denen eine SOAP-Erweiterung die SOAP-Nachricht überprüfen oder ändern könnte, sind in der SoapMessageStage-Enumeration definiert. In diesem Fall nimmt die SOAP-Erweiterung die Verschlüsselung in der AfterSerialize-Phase und die Entschlüsselung in der BeforeDeserialize-Phase vor.
Wenn eine SOAP-Erweiterung den Inhalt einer SOAP-Nachricht ändert, müssen die Änderungen in der Regel sowohl auf dem Client als auch auf dem Server vorgenommen werden. Dies bedeutet Folgendes: Wenn eine SOAP-Erweiterung auf dem Client ausgeführt wird und die SOAP-Nachricht verschlüsselt, muss eine entsprechende SOAP-Erweiterung die SOAP-Nachricht auf dem Server entschlüsseln. Wenn die SOAP-Nachricht nicht entschlüsselt wird, kann die ASP.NET-Infrastruktur die SOAP-Nachricht nicht in ein Objekt deserialisieren.
Natürlich kann eine SOAP-Erweiterung, die die SOAP-Nachricht nicht ändert (z. B. SOAP-Erweiterungen, die SOAP-Nachrichten nur protokollieren), nur auf dem Client oder nur auf dem Server ausgeführt werden. In diesem Fall erhält der Empfänger dieselbe SOAP-Nachricht, die er empfangen hätte, wenn keine SOAP-Erweiterung ausgeführt würde, und die ASP.NET-Infrastruktur kann die SOAP-Nachricht deserialisieren. Wenn die SOAP-Erweiterung die SOAP-Nachricht nicht auf eine Weise ändert, die eine Deserialisierung unmöglich macht, braucht die SOAP-Erweiterung außerdem nicht sowohl auf dem Client als auch auf dem Server ausgeführt zu werden.
Erweitern der SOAPExtension-Klasse
Leiten Sie eine Klasse von der SoapExtension-Klasse ab, um eine SOAP-Erweiterung zu implementieren. Es gibt drei Methoden der SOAPExtension-Klasse, die implementiert werden sollten oder müssen:
ChainStream, eine virtuelle Methode
GetInitializer, eine abstrakte Methode mit zwei Signaturen
Initialize, eine abstrakte Methode
ProcessMessage, eine abstrakte Methode
Die Vorgehensweise beim Implementieren dieser Methoden wird im Thema "Exemplarische Vorgehensweise: Ändern der SOAP-Nachricht mit SOAP-Erweiterungen" erläutert, in dem die Verfahrensweise Schritt für Schritt beschrieben ist.
Der ChainStream-Methode wird ein Stream-Objekt übergeben, und sie gibt ein Stream-Objekt zurück. Da die SOAP-Erweiterung während jeder SoapMessageStage ausgeführt wird und die SOAP-Nachricht ändert, muss eine SOAP-Erweiterung aus dem in ChainStream übergebenen Stream lesen und in den von ChainStream zurückgegebenen Stream schreiben. Deshalb ist es innerhalb der ChainStream-Methode wichtig, beide Stream-Verweise Membervariablen zuzuweisen.
Die von SoapExtension abgeleitete Klasse verwendet die GetInitializer-Methode und die Initialize-Methode zum Initialisieren interner Daten auf der Grundlage des Webdiensts oder der Webdienstmethode, auf die sie angewendet wird. Beispiel: Eine SOAP-Erweiterung, die die an und von einer Webdienstmethode gesendete SOAP-Nachricht protokolliert, könnte den Namen einer Datei initialisieren, um die Protokollierungsinformationen (auf der Grundlage des Namens des Webdiensts oder der Webdienstmethode, mit der die SOAP-Erweiterung ausgeführt wird) zu speichern.
An welchem Punkt die Webdienstinfrastruktur die GetInitializer-Methode aufruft und welche Parameter der Methode übergeben werden, hängt wie folgt von der Konfiguration der SOAP-Erweiterung ab:
Wenn die SOAP-Erweiterung mit einem Attribut konfiguriert ist, wird GetInitializer von der Webdienstinfrastruktur aufgerufen, wenn zum ersten Mal auf eine Webdienst-method zugegriffen wird.
Wenn die SOAP-Erweiterung in einer Konfigurationsdatei konfiguriert ist, wird GetInitializer von der Webdienstinfrastruktur nur beim ersten Zugriff auf den gesamten Webdienst aufgerufen.
Die Webdienstinfrastruktur speichert das Objekt zwischen, das die GetInitializer-Methode zurückgibt. Anschließend übergibt die Infrastruktur das Initialisierungsobjekt jedes Mal, wenn die SOAP-Erweiterung mit diesem Webdienst oder dieser Webdienstmethode ausgeführt wird, an die Initialize-Methode.
Die eigentliche erweiterte Verarbeitung, die über die Standard-SOAP-Verarbeitung hinausgeht, wird von der ProcessMessage-Methode ausgeführt. Jedes Mal, wenn die Webdienstinfrastruktur ProcessMessage aufruft, übergibt sie eine Instanz einer Klasse (als Argument), die von SoapMessage abgeleitet ist und Informationen über die SOAP-Nachricht in dieser speziellen Phase enthält. Wenn die SOAP-Erweiterung mit einem Webdienst ausgeführt wird, wird ein SoapServerMessage-Objekt übergeben. Wenn die SOAP-Erweiterung mit einem Webserviceclient ausgeführt wird, wird ein SoapClientMessage-Objekt übergeben.
SOAP-Erweiterungen und Ausnahmen
SOAP-Erweiterungen dürfen nie selbst Ausnahmen auslösen. Sie können jedoch der Exception-Eigenschaft im SoapMessage-Objekt, das in die ProcessMessage-Methode übergeben wird, Ausnahmeinformationen hinzufügen.
Sie können auch als anwendungsweiter Ausnahmehandler dienen, indem sie die gleiche Funktion zum Abfangen aller Ausnahmen in der Anwendung verwenden, für die die SOAP-Erweiterung installiert ist, und ein bestimmtes Verhalten (einschließlich Änderung des zurückgegebenen SOAP-Fehlers) zeigen.
Aufrufreihenfolge von SOAP-Erweiterungsmethoden
Sie haben sich die Methoden angesehen, die von einer SOAP-Erweiterung überschrieben werden. Betrachten Sie nun, wann die Webdienstinfrastruktur beim Aufrufen einer Webdienstmethode SOAP-Erweiterungsmethoden aufruft. Die folgenden Schritte setzen voraus, dass die SOAP-Erweiterung sowohl auf dem Client als auch auf dem Server ausgeführt wird. Wenn die SOAP-Erweiterung nicht sowohl auf dem Client als auch auf dem Server ausgeführt wird, werden die Schritte, die die auf beiden ausgeführte SOAP-Erweiterung betreffen, von .NET Framework ignoriert.
Clientseite bereitet eine Anforderungsnachricht vor
Ein Client ruft eine Methode für die Proxyklasse auf.
Eine neue Instanz der SOAP-Erweiterung wird auf dem Client erstellt.
Wenn diese SOAP-Erweiterung zum ersten Mal mit diesem Webdienst auf dem Client ausgeführt wird, wird die GetInitializer-Methode für die SOAP-Erweiterung aufgerufen, die auf dem Client ausgeführt wird.
Die Initialize-Methode wird aufgerufen.
Die ChainStream-Methode wird aufgerufen.
Die ProcessMessage-Methode wird aufgerufen, wobei SoapMessageStage auf BeforeSerialize festgelegt ist.
ASP.NET des Clientcomputers serialisiert die Argumente der Webdienstmethode in XML.
Die ProcessMessage-Methode wird aufgerufen, wobei SoapMessageStage auf AfterSerialize festgelegt ist.
ASP.NET des Clientcomputers sendet die SOAP-Nachricht über das Netzwerk an den Webserver, der den Webdienst hostet.
Serverseite empfängt eine Anforderungsnachricht und bereitet eine Antwort vor
ASP.NET des Webservers empfängt die SOAP-Nachricht.
Eine neue Instanz der SOAP-Erweiterung wird auf dem Webserver erstellt.
Wenn diese SOAP-Erweiterung auf dem Webserver zum ersten Mal mit diesem Webdienst auf der Serverseite ausgeführt wird, wird die GetInitializer-Methode für die SOAP-Erweiterung aufgerufen, die auf dem Server ausgeführt wird.
Die Initialize-Methode wird aufgerufen.
Die ChainStream-Methode wird aufgerufen.
Die ProcessMessage-Methode wird aufgerufen, wobei SoapMessageStage auf BeforeDeserialize festgelegt ist.
ASP.NET deserialisiert die Argumente innerhalb von XML.
Die ProcessMessage-Methode wird aufgerufen, wobei SoapMessageStage auf AfterDeserialize festgelegt ist.
ASP.NET erstellt eine neue Instanz der Klasse, die den Webdienst implementiert, und ruft die Webdienstmethode auf, wobei die deserialisierten Argumente übergeben werden. Dieses Objekt befindet sich auf demselben Computer wie der Webserver.
Die Webdienstmethode führt ihren Code aus und legt schließlich den Rückgabewert und die out-Parameter fest.
Die ProcessMessage-Methode wird aufgerufen, wobei SoapMessageStage auf BeforeSerialize festgelegt ist.
ASP.NET des Webservers serialisiert den Rückgabewert und die out-Parameter in XML.
Die ProcessMessage-Methode wird aufgerufen, wobei SoapMessageStage auf AfterSerialize festgelegt ist.
ASP.NET sendet die SOAP-Nachricht über das Netzwerk zurück an den Webdienstclient.
Clientseite empfängt eine Antwortnachricht
ASP.NET des Clientcomputers empfängt die SOAP-Nachricht.
Die ProcessMessage-Methode wird aufgerufen, wobei SoapMessageStage auf BeforeDeserialize festgelegt ist.
ASP.NET deserialisiert die XML in den Rückgabewert und die out-Parameter.
Die ProcessMessage-Methode wird aufgerufen, wobei SoapMessageStage auf AfterDeserialize festgelegt ist.
ASP.NET übergibt den Rückgabewert und die out-Parameter an die Instanz der Proxyklasse.
Der Client empfängt den Rückgabewert und die out-Parameter.
Implementieren der SOAP-Erweiterung
Es gibt zwei Möglichkeiten, eine SOAP-Erweiterung entweder unter einer Client- oder unter einer Serveranwendung auszuführen. Zuerst können Sie die Anwendung so konfigurieren, dass sie die Erweiterung ausführt. Bearbeiten Sie den Abschnitt <soapExtensionTypes>-Element innerhalb der Datei Web.config, um die SOAP-Erweiterung so zu konfigurieren, dass sie für alle Webmethoden unter allen Webdiensten, insbesondere vroot, ausgeführt wird. Der folgende Code zeigt, dass sich der type-Attributwert in einer Zeile befinden und den vollqualifizierten Namen der Erweiterung (einschließlich Version, Kultur und öffentliches Schlüsseltoken der signierten Assembly) enthalten muss.
<configuration>
<system.web>
<webServices>
<soapExtensionTypes>
<add type="Contoso.MySoapExtension, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
priority="1" group="0"/>
</soapExtensionTypes>
</webServices>
</system.web>
</configuration>
Als nächstes können Sie ein benutzerdefiniertes Attribut erstellen, das auf eine Webdienstmethode angewendet wird. Zum Erstellen des benutzerdefinierten Attributs erstellen Sie eine Klasse, die von SoapExtensionAttribute abgeleitet ist. Ausführliche Informationen über das Erstellen eines benutzerdefinierten Attributs finden Sie unter Gewusst wie: Implementieren einer SOAP-Erweiterung. Weitere Informationen zum Erstellen benutzerdefinierter Attribute finden Sie unter "Erstellen benutzerdefinierter Attribute".
Hinweis: |
---|
Beim Implementieren einer SOAP-Erweiterung besteht die Möglichkeit eines Denial-of-Service-Angriffs (DoS), wenn die Erweiterung den Datenstrom mit XmlTextReader liest. Ein solcher Angriff lässt sich unter anderem dadurch verhindern, dass Sie die ProhibitDtd-Eigenschaft auf true festlegen. |
Prioritäten und Prioritätsgruppen
SOAP-Erweiterungen kann über Attribute oder Konfigurationen eine Priorität zugewiesen werden, mit der die relative Ausführungsreihenfolge ermittelt wird, wenn mehrere SOAP-Erweiterung für die Ausführung mit einer XML-Webdienstmethode konfiguriert sind. Je höher die Priorität einer SOAP-Erweiterung ist, umso näher wird sie an der SOAP-Nachricht ausgeführt, die über das Netzwerk gesendet oder empfangen wird. SOAP-Erweiterungen gehören zu einer von drei Prioritätsgruppen. Innerhalb jeder Gruppe unterscheidet die priority-Eigenschaft die einzelnen Member. Je niedriger der Wert für die priority-Eigenschaft ist, umso höher ist die relative Priorität (0 ist die höchste Priorität).
Die drei Gruppen für die relative Priorität von SOAP-Erweiterungen sind: SOAP-Erweiterungen, die mit einem Attribut konfiguriert wurden, und SOAP-Erweiterungen, die in der Konfigurationsdatei mit der group-Einstellung 0 oder 1 angegeben wurden. Ihre Prioritäten haben folgende Reihenfolge:
Gruppe mit höchster Priorität: SOAP-Erweiterungen, die mit einer Konfigurationsdatei mit der group-Einstellung 0 konfiguriert wurden.
Gruppe mit mittlerer Priorität: Mit einem Attribut konfigurierte SOAP-Erweiterungen.
Gruppe mit niedrigster Priorität: SOAP-Erweiterungen, die mit einer Konfigurationsdatei mit der group-Einstellung 1 konfiguriert wurden.
Das folgende Codebeispiel zeigt eine Konfigurationsdatei, die angibt, dass die Logger.LoggerExtension
-SOAP-Erweiterung innerhalb der Gruppe 0
für relative Priorität ausgeführt wird und die Priorität 1
besitzt.
<configuration>
<system.web>
<webServices>
<soapExtensionTypes>
<add type="Logger.LoggerExtension,logger"
priority="1"
group="0" />
</soapExtensionTypes>
</webServices>
</system.web>
</configuration>
Siehe auch
Aufgaben
Gewusst wie: Implementieren einer SOAP-Erweiterung
Referenz
SoapExtension
SoapExtensionAttribute
SoapMessageStage
LogicalMethodInfo
Konzepte
SOAP-Nachrichtenänderung mit SOAP-Erweiterungen
Aufbau der Lebensdauer von XML-Webdiensten
Erstellen von XML-Webdienstclients
Weitere Ressourcen
Configuring Applications
XML-Webdienste, die ASP.NET verwenden
Copyright © 2007 by Microsoft Corporation. Alle Rechte vorbehalten.