Entwerfen von Dienstverträgen

In diesem Thema wird erläutert, was Dienstverträge sind, wie sie definiert werden, welche Vorgänge verfügbar sind (und die Implikationen des zugrunde liegenden Meldungsaustauschs), welche Datentypen verwendet werden sowie andere Aspekte, die Sie beim Entwerfen von Vorgängen unterstützen, die den Anforderungen Ihres Szenarios gerecht werden.

Erstellen eines Dienstvertrags

Dienste machen eine Reihe von Vorgängen verfügbar. In WCF-Anwendungen (Windows Communication Foundation) werden Vorgänge definiert, indem Sie eine Methode erstellen und diese mit dem OperationContractAttribute-Attribut markieren. Zum Erstellen eines Dienstvertrags gruppieren Sie dann die Vorgänge, indem Sie sie in einer Schnittstelle deklarieren, die mit dem ServiceContractAttribute-Attribut markiert wurde, oder indem Sie sie in einer Klasse definieren, die mit dem gleichen Attribut markiert wurde. (Ein einfaches Beispiel finden Sie unter Tutorial: Definieren eines Windows Communication Foundation-Dienstvertrags.)

Methoden ohne OperationContractAttribute-Attribut sind keine Dienstvorgänge und werden von WCF-Diensten nicht verfügbar gemacht.

In diesem Thema werden die folgenden Entscheidungspunkte beschrieben, wenn ein Dienstvertrag entworfen wird:

  • Ob Klassen oder Schnittstellen verwendet werden sollen

  • Wie die Datentypen angegeben werden, die Sie austauschen möchten

  • Die Typen von Austauschmustern, die Sie verwenden können

  • Ob Sie einen expliziten Sicherheitsanforderungen-Teil des Vertrags erstellen können

  • Die Einschränkungen für Vorgangseingaben und -ausgaben

Klassen oder Schnittstellen

Klassen und Schnittstellen stellen Funktionsgruppierungen dar und können daher beide zum Definieren eines WCF-Dienstvertrags verwendet werden. Es wird allerdings empfohlen, Schnittstellen zu verwenden, da sie Dienstverträge direkt modellieren. Ohne Implementierung definieren Schnittstellen lediglich eine Gruppierung von Methoden mit bestimmten Signaturen. Implementieren Sie eine Dienstvertragsschnittstelle, und Sie haben damit gleichzeitig einen WCF-Dienst implementiert.

Dienstvertragsschnittstellen bieten dieselben Vorteile wie verwaltete Schnittstellen:

  • Dienstvertragsschnittstellen können jede Anzahl anderer Dienstvertragsschnittstellen erweitern.

  • Eine einzelne Klasse kann jede Anzahl von Dienstverträgen implementieren, indem sie diese Dienstvertragsschnittstelle implementiert.

  • Sie können die Implementierung eines Dienstvertrags bearbeiten, indem Sie die Schnittstellenimplementierung ändern, während der Dienstvertrag unverändert bleibt.

  • Sie können verschiedene Versionen eines Diensts erstellen, indem Sie die alte und die neue Schnittstelle implementieren. Alte Clients stellen eine Verbindung mit der ursprünglichen Version her, während neuere Clients eine Verbindung mit der neuen Version herstellen können.

Hinweis

Bei der Vererbung von anderen Dienstvertragsschnittstellen können Sie Vorgangseigenschaften, wie z. B. den Name und den Namespace, nicht außer Kraft setzen. Wenn Sie dies dennoch versuchen, erstellen Sie im aktuellen Dienstvertrag einen neuen Vorgang.

Ein Beispiel für die Verwendung einer Schnittstelle zum Erstellen eines Dienstvertrags finden Sie unter Vorgehensweise: Erstellen eines Diensts mit einer Vertragsschnittstelle.

Sie können allerdings eine Klasse verwenden, um einen Dienstvertrag zu definieren und gleichzeitig zu implementieren. Der Vorteil des Erstellens Ihrer Dienste durch direktes Anwenden von ServiceContractAttribute und OperationContractAttribute auf die Klasse und die Methoden der Klasse liegen in der Geschwindigkeit und der Einfachheit. Die Nachteile liegen darin begründet, dass verwaltete Klassen keine mehrfache Vererbung unterstützen. Als Ergebnis kann immer nur ein Dienstvertrag gleichzeitig implementiert werden. Außerdem ändern alle Modifikationen der Klasse oder Methode den öffentlichen Vertrag für diesen Dienst, der unveränderte Clients daran hindern kann, Ihren Dienst zu verwenden. Weitere Informationen finden Sie unter Implementieren von Dienstverträgen.

Ein Beispiel für die Verwendung einer Klasse zum Erstellen eines Dienstvertrags mit gleichzeitiger Implementierung finden Sie unter Vorgehensweise: Erstellen eines Windows Communication Foundation-Vertrags mit einer Klasse.

An diesem Punkt sollten Sie den Unterschied zwischen dem Definieren des Dienstvertrags mithilfe einer Schnittstelle und mithilfe einer Klasse kennen. Der nächste Schritt besteht darin, zu entscheiden, welche Daten zwischen einem Dienst und seinen Clients hin- und herübergeben werden können.

Parameter und Rückgabewerte

Jeder Vorgang verfügt über einen Rückgabewert und einen Parameter, auch wenn diese void sind. Im Gegensatz zu einer lokalen Methode, in der Sie Verweise auf Objekte von einem Objekt zu einem anderen übergeben können, werden bei Dienstvorgängen keine Verweise auf Objekte übergeben. Stattdessen werden Kopien der Objekte übergeben.

Das ist wichtig, da jeder in einem Parameter oder einem Rückgabewert verwendete Typ serialisiert werden muss. Das bedeutet, dass es möglich sein muss, ein Objekt dieses Typs in einen Datenstrom und einen Datenstrom in ein Objekt umzuwandeln.

Primitive Typen sind standardmäßig, wie viele Typen in .NET Framework, serialisierbar.

Hinweis

Der Wert der Parameternamen in der Vorgangssignatur ist Teil des Vertrags, und die Groß- und Kleinschreibung wird beachtet. Wenn Sie denselben Parameternamen lokal verwenden, aber den Namen in den veröffentlichten Metadaten ändern möchten, finden Sie entsprechende Informationen unter System.ServiceModel.MessageParameterAttribute.

Datenverträge

Dienstorientierte Anwendungen wie WCF-Anwendungen (Windows Communication Foundation) wurden entwickelt, um mit einer möglichst großen Anzahl von Clientanwendungen auf Microsoft- und Nicht-Microsoft-Plattformen verwendet werden zu können. Für die höchstmögliche Interoperabilität sollten Sie Ihre Typen mit dem DataContractAttribute- und dem DataMemberAttribute-Attribut markieren, um einen Datenvertrag zu erstellen, der dem Teil des Dienstvertrags entspricht, der die Daten beschreibt, die durch die Dienstvorgänge ausgetauscht werden.

Datenverträge sind Abonnementverträge: Es werden keine Typen- oder Datenmitglieder serialisiert, es sei denn, Sie wenden das Datenvertragsattribut ausdrücklich an. Datenverträge stehen nicht mit dem Zugriffsumfang des verwalteten Codes in Verbindung: Private Datenmitglieder können serialisiert und für den öffentlichen Zugriff an einen beliebigen Ort gesendet werden. (Ein einfaches Beispiel eines Datenvertrags finden Sie unter Vorgehensweise: Erstellen eines grundlegenden Datenvertrags für eine Klasse oder Struktur.) WCF verarbeitet die Definition der zugrunde liegenden SOAP-Nachrichten, die die Funktionalität des Vorgangs sowie die Serialisierung der Datentypen in den und aus dem Nachrichtentext ermöglichen. Solange Ihre Datentypen serialisierbar sind, müssen Sie sich beim Erstellen von Vorgängen keine Gedanken über die zugrunde liegende Meldungsaustauschinfrastruktur machen.

Eine typische WCF-Anwendung verwendet zwar die Attribute DataContractAttribute und DataMemberAttribute, um Datenverträge für Vorgänge zu erstellen, Sie können aber auch andere Serialisierungsmechanismen verwenden. Die standardmäßigen Mechanismen ISerializable, SerializableAttribute und IXmlSerializable können alle zum Serialisieren Ihrer Datentypen in den zugrunde liegenden SOAP-Nachrichten für den Transport zwischen Anwendungen verwendet werden. Sie können weitere Serialisierungsstrategien anwenden, wenn die Datentypen spezielle Unterstützung benötigen. Weitere Informationen zu den Optionen für die Serialisierung von Datentypen in WCF-Anwendungen finden Sie unter Angeben von Datenübertragung in Dienstverträgen.

Zuordnen von Parametern und Rückgabewerten zu Nachrichtenaustauschvorgängen

Dienstvorgänge werden von einem zugrunde liegenden Austausch von SOAP-Meldungen unterstützt, die Anwendungsdaten hin- und herübertragen, zusätzlich zu den Daten, die die Anwendung benötigt, um bestimmte standardmäßige Sicherheits-, Transaktions- und Sitzungsfunktionen zu unterstützen. Da dies der Fall ist, schreibt die Signatur eines Dienstvorgangs ein bestimmtes zugrunde liegendes Nachrichtenaustauschmuster (Message Exchange Pattern, MEP) vor, das die Datenübertragung und die Funktionen unterstützt, die ein Vorgang erfordert. Sie können drei Muster im WCF-Programmiermodell angeben: „Anforderung/Antwort“, „Unidirektional“ und „Duplex“.

Anforderung/Antwort

Anforderung/Antwort ist ein Muster, in dem ein Anforderungssender (eine Clientanwendung) eine Antwort empfängt, mit der die Anfrage kombiniert wird. Dabei handelt es sich um das standardmäßige Meldungsaustauschmuster, da es einen Vorgang unterstützt, in dem mindestens ein Parameter an den Vorgang übergeben und ein Rückgabewert zurück an den Aufrufer übergeben wird. Das folgende C#-Codebeispiel zeigt einen einfachen Dienstvorgang, der eine Zeichenfolge als Parameter akzeptiert und eine Zeichenfolge zurückgibt:

[OperationContractAttribute]  
string Hello(string greeting);  

Im Folgenden sehen Sie den entsprechenden Visual Basic-Code:

<OperationContractAttribute()>  
Function Hello (ByVal greeting As String) As String  

Diese Vorgangssignatur schreibt die Form des zugrunde liegenden Meldungsaustauschs vor. Ohne Korrelation kann WCF nicht ermitteln, für welchen Vorgang der Rückgabewert vorgesehen ist.

Hinweis: Falls Sie kein anderes zugrunde liegendes Nachrichtenmuster angeben, sind auch Dienstvorgänge, die void (in Visual Basic: Nothing) zurückgeben, Nachrichtenaustauschvorgänge vom Typ „Anforderung/Antwort“. Als Ergebnis für Ihren Vorgang folgt daraus, dass der Client, falls er den Vorgang nicht asynchron aufruft, die Verarbeitung anhält, bis die Antwortmeldung empfangen wird, auch wenn diese Meldung normalerweise leer ist. Das folgende C#-Codebeispiel zeigt einen Vorgang, der erst zurückgegeben wird, wenn der Client als Antwort eine leere Meldung empfangen hat:

[OperationContractAttribute]  
void Hello(string greeting);  

Im Folgenden sehen Sie den entsprechenden Visual Basic-Code:

<OperationContractAttribute()>  
Sub Hello (ByVal greeting As String)  

Das vorherige Beispiel kann die Clientleistung und die Antwortzeit verschlechtern, wenn der Vorgang lange Zeit dauert. Anforderungs-/Antwort-Vorgänge haben aber selbst dann Vorteile, wenn sie void zurückgeben. Der offensichtlichste Vorteil besteht darin, dass SOAP-Fehler in der Antwortnachricht zurückgegeben werden können, die anzeigen, dass in der Kommunikation oder Verarbeitung dienstbedingte Fehlerbedingungen eingetreten sind. SOAP-Fehler, die in einem Dienstvertrag angegeben werden, werden der Clientanwendung als FaultException<TDetail>-Objekte übergeben, wobei der Typparameter dem im Dienstvertrag angegebenen Typ entspricht. Dies vereinfacht die Benachrichtigung von Clients über Fehlerbedingungen in WCF-Diensten. Weitere Informationen zu Ausnahmen, zu SOAP-Fehlern und zur Fehlerbehandlung finden Sie unter Angeben und Behandeln von Fehlern in Verträgen und Diensten. Ein Beispiel für einen Anforderung/Antwort-Dienst und einen entsprechenden Client finden Sie unter Vorgehensweise: Erstellen eines Anforderung-Antwort-Vertrags. Weitere Informationen zu Problemen mit dem Muster „Anforderung/Antwort“ finden Sie unter Anforderung-Antwort-Dienste.

Unidirektional

Wenn der Client einer WCF-Dienstanwendung nicht auf die Beendigung des Vorgangs warten soll und keine SOAP-Fehler verarbeitet, kann ein unidirektionales Nachrichtenmuster angegeben werden. In einem unidirektionalen Vorgang ruft ein Client einen Vorgang auf und fährt mit der Verarbeitung fort, nachdem WCF die Nachricht ins Netzwerk geschrieben hat. Normalerweise bedeutet dies, dass der Client die Ausführung fast unverzüglich fortsetzt, sofern die in der ausgehenden Nachricht enthaltene Datenmenge nicht übermäßig groß ist (und sofern beim Senden der Daten kein Fehler auftritt). Dieser Typ des Nachrichtenaustauschmusters unterstützt ereignisähnliches Verhalten gegenüber einem Client zu einer Dienstanwendung.

Ein Meldungsaustausch, in dem eine Meldung gesendet und keine empfangen wird, kann keinen Dienstvorgang unterstützen, der einen anderen Rückgabewert als void angibt. In diesem Fall wird eine InvalidOperationException-Ausnahme ausgelöst.

Eine fehlende Rückgabemeldung bedeutet außerdem, dass keine SOAP-Fehler zurückgegeben werden können, um Fehler bei Bearbeitung und Kommunikation anzuzeigen. (Kommunizieren von Fehlerinformationen bei unidirektionalen Vorgängen erfordert ein Duplex-Meldungsaustauschmuster.)

Um einen unidirektionalen Meldungsaustausch für einen Vorgang anzugeben, der void zurückgibt, legen Sie die IsOneWay-Eigenschaft auf true fest, wie im folgenden C#-Codebeispiel gezeigt:

[OperationContractAttribute(IsOneWay=true)]  
void Hello(string greeting);  

Im Folgenden sehen Sie den entsprechenden Visual Basic-Code:

<OperationContractAttribute(IsOneWay := True)>  
Sub Hello (ByVal greeting As String)  

Diese Methode ist mit dem vorherigen Anforderungs-/Antwortbeispiel identisch, aber das Festlegen der IsOneWay-Eigenschaft auf true bedeutet, dass der Dienstvorgang, obwohl die Methode identisch ist, keine Rückgabemeldung sendet und Clients unverzüglich zurückgegeben werden, sobald die ausgehende Meldung der Kanalebene übergeben wurde. Ein Beispiel finden Sie unter Vorgehensweise: Erstellen eines unidirektionalen Vertrags. Weitere Informationen zum unidirektionalen Muster finden Sie unter Unidirektionale Dienste.

Duplex

Ein Duplexmuster wird durch die Fähigkeit des Diensts und des Clients zum unabhängigen Senden von Nachrichten untereinander charakterisiert, wenn unidirektionale oder Anforderungs-/Antwortmeldungen verwendet werden. Diese Form einer bidirektionalen Kommunikation ist für Dienste nützlich, die direkt mit dem Client kommunizieren müssen, oder zum Bereitstellen einer asynchronen Erfahrung auf beiden Seiten eines Nachrichtenaustauschs, einschließlich ereignisähnlichen Verhaltens.

Das Duplexmuster ist aufgrund der zusätzlichen Mechanismen für die Kommunikation mit dem Client etwas komplexer als das Anforderungs-/Antwortmuster und das unidirektionale Muster.

Für einen Duplexvertrag müssen Sie auch einen Rückrufvertrag entwerfen und den Typ dieses Rückrufvertrags der CallbackContract-Eigenschaft des ServiceContractAttribute-Attributs zuweisen, das den Dienstvertrag markiert.

Zum Implementieren eines Duplexmusters müssen Sie eine zweite Schnittstelle erstellen, die die Methodendeklarierungen enthält, die auf dem Client aufgerufen werden.

Ein Beispiel für das Erstellen eines Diensts und eines Clients, der auf diesen Dienst zugreift, finden Sie unter Vorgehensweise: Erstellen eines Duplexvertrags sowie unter Vorgehensweise: Zugreifen auf Dienste mit einem Duplexvertrag. Ein funktionierendes Beispiel finden Sie unter Duplex. Weitere Informationen zu Problemen bei der Verwendung von Duplexdiensten finden Sie unter Duplexdienste.

Achtung

Wenn ein Dienst eine Duplexmeldung empfängt, überprüft er das ReplyTo-Element in dieser eingehenden Meldung, um zu bestimmen, wohin die Antwort gesendet werden soll. Wenn der zum Empfangen der Meldung verwendete Kanal nicht gesichert ist, kann ein nicht vertrauenswürdiger Client eine bösartige Meldung mit dem ReplyTo-Element eines Zielcomputers senden, was zu einem Denial Of Service (DOS) auf diesem Zielcomputer führt.

Out-Parameter und Ref-Parameter

In den meisten Fällen können Sie in-Parameter (in Visual Basic: ByVal) sowie out- und ref-Parameter (in Visual Basic: ByRef) verwenden. Da die out- und ref-Parameter anzeigen, dass Daten aus einem Vorgang zurückgegeben werden, gibt eine Vorgangssignatur wie die folgende an, dass ein Anforderungs-/Antwortvorgang erforderlich ist, obwohl die Vorgangssignatur void zurückgibt.

[ServiceContractAttribute]  
public interface IMyContract  
{  
  [OperationContractAttribute]  
  public void PopulateData(ref CustomDataType data);  
}  

Im Folgenden sehen Sie den entsprechenden Visual Basic-Code:

<ServiceContractAttribute()> _  
Public Interface IMyContract  
  <OperationContractAttribute()> _  
  Public Sub PopulateData(ByRef data As CustomDataType)  
End Interface  

Die einzigen Ausnahmen sind jene Fälle, in denen die Signatur über eine besondere Struktur verfügt. Sie können beispielsweise die NetMsmqBinding-Bindung nur dann zum Kommunizieren mit Clients verwenden, wenn die zum Deklarieren eines Vorgangs verwendete Methode void zurückgibt. Es dürfen keine Ausgabewerte vorliegen, weder ein Rückgabewert noch ein ref-Parameter oder ein out-Parameter.

Außerdem ist bei der Verwendung der out- und ref-Parameter erforderlich, dass der Vorgang über eine zugrunde liegende Antwortmeldung verfügt, um das geänderte Objekt zurückzugeben. Wenn es sich bei dem Vorgang um einen unidirektionalen Vorgang handelt, wird zur Laufzeit eine InvalidOperationException-Ausnahme ausgelöst.

Angeben einer Meldungsschutzebene für den Vertrag

Wenn Sie den Vertrag entwerfen, müssen Sie sich außerdem für eine Meldungsschutzebene für Dienste entscheiden, die den Vertrag implementieren. Dies ist nur notwendig, wenn Meldungssicherheit auf die Bindung im Endpunkt des Vertrags angewendet wird. Wenn die Sicherheit für die Bindung deaktivert wurde (wenn also die vom System bereitgestellte Bindung den System.ServiceModel.SecurityMode auf den Wert SecurityMode.None festlegt), müssen Sie sich nicht für eine Meldungsschutzebene für den Vertrag entscheiden. In den meisten Fällen bieten vom System bereitgestellte Bindungen mit angewendeter Sicherheit auf Nachrichtenebenen eine ausreichende Schutzebene, sodass Sie sich nicht bei jedem Vorgang oder jeder Nachricht Gedanken um die Schutzebene machen müssen.

Die Schutzebene ist ein Wert, der angibt, ob die Meldungen (oder Meldungsteile), die einen Dienst unterstützen, signiert, signiert und verschlüsselt oder ohne Signaturen und Verschlüsselung gesendet werden. Die Schutzebene kann in unterschiedlichem Umfang festgelegt werden: auf Dienstebene, für einen bestimmten Vorgang, für eine Meldung innerhalb dieses Vorgangs oder für einen Meldungsteil. Auf einen Bereich festgelegte Werte werden zum Standardwert für kleinere Bereiche, außer wenn diese explizit außer Kraft gesetzt werden. Wenn eine Bindungskonfiguration die erforderliche Mindestschutzebene für den Vertrag nicht bereitstellen kann, wird eine Ausnahme ausgegeben. Wenn für den Vertrag keine Schutzebenenwerte explizit festgelegt sind, steuert die Bindungskonfiguration die Schutzebene für alle Meldungen, sofern die Bindung über Meldungssicherheit verfügt. Dies ist das Standardverhalten.

Wichtig

Die Entscheidung über das explizite Festlegen verschiedener Umfänge eines Vertrags auf weniger als die vollständige Schutzebene von ProtectionLevel.EncryptAndSign ist normalerweise eine Entscheidung, die die Leistung verbessert, während die Sicherheit reduziert wird. In diesen Fällen hängen Ihre Entscheidungen von den Vorgängen und dem Wert der ausgetauschten Daten ab. Weitere Informationen finden Sie unter Sichern von Diensten.

Im folgenden Codebeispiel wird weder die ProtectionLevel- noch die ProtectionLevel-Eigenschaft für den Vertrag festgelegt.

[ServiceContract]  
public interface ISampleService  
{  
  [OperationContractAttribute]  
  public string GetString();  
  
  [OperationContractAttribute]  
  public int GetInt();
}  

Im Folgenden sehen Sie den entsprechenden Visual Basic-Code:

<ServiceContractAttribute()> _  
Public Interface ISampleService  
  
  <OperationContractAttribute()> _  
  Public Function GetString()As String  
  
  <OperationContractAttribute()> _  
  Public Function GetData() As Integer  
  
End Interface  

Beim Interagieren mit einer ISampleService-Implementierung in einem Endpunkt mit einer standardmäßigen WSHttpBinding (der standardmäßige System.ServiceModel.SecurityMode ist Message) werden alle Meldungen verschlüsselt und signiert, da es sich dabei um die Standardschutzebene handelt. Wenn jedoch ein ISampleService-Dienst mit einer standardmäßigen BasicHttpBinding verwendet wird (der standardmäßige SecurityMode ist None), werden alle Nachrichten als Text gesendet, da es keine Sicherheit für diese Bindung gibt und somit die Schutzebene ignoriert wird (die Nachrichten werden also weder verschlüsselt noch signiert). Würde der SecurityMode in Message geändert, würden die Nachrichten verschlüsselt und signiert (da es sich in diesem Fall um die Standardschutzebene der Bindung handeln würde).

Wenn Sie die Schutzanforderungen für den Vertrag explizit angeben oder anpassen möchten, legen Sie die ProtectionLevel-Eigenschaft (oder die ProtectionLevel-Eigenschaften im kleineren Umfang) auf die für den Dienstvertrag erforderliche Ebene fest. In diesem Fall ist bei der Verwendung einer expliziten Einstellung erforderlich, dass die Bindung diese Einstellung mindestens für den verwendeten Umfang unterstützt. Im folgenden Codebeispiel wird ein ProtectionLevel-Wert explizit für den GetGuid-Vorgang angegeben.

[ServiceContract]  
public interface IExplicitProtectionLevelSampleService  
{  
  [OperationContractAttribute]  
  public string GetString();  
  
  [OperationContractAttribute(ProtectionLevel=ProtectionLevel.None)]  
  public int GetInt();
  [OperationContractAttribute(ProtectionLevel=ProtectionLevel.EncryptAndSign)]  
  public int GetGuid();
}  

Im Folgenden sehen Sie den entsprechenden Visual Basic-Code:

<ServiceContract()> _
Public Interface IExplicitProtectionLevelSampleService
    <OperationContract()> _
    Public Function GetString() As String
    End Function
  
    <OperationContract(ProtectionLevel := ProtectionLevel.None)> _
    Public Function GetInt() As Integer
    End Function
  
    <OperationContractAttribute(ProtectionLevel := ProtectionLevel.EncryptAndSign)> _
    Public Function GetGuid() As Integer
    End Function
  
End Interface  

Ein Dienst, der diesen IExplicitProtectionLevelSampleService-Vertrag implementiert und über einen Endpunkt verfügt, der die standardmäßige WSHttpBinding (der standardmäßige System.ServiceModel.SecurityMode ist Message) verwendet, hat das folgende Verhalten:

  • Die GetString-Vorgangsmeldungen werden verschlüsselt und signiert.

  • Die GetInt-Vorgangsmeldungen werden als unverschlüsselter und unsignierter Text gesendet.

  • Der GetGuid-Vorgang System.Guid wird in einer Nachricht zurückgegeben, die verschlüsselt und signiert wird.

Weitere Informationen zu Schutzebenen und deren Verwendung finden Sie unter Grundlagen der Schutzebene. Weitere Informationen zur Sicherheit finden Sie unter Sichern von Diensten.

Andere Vorgangssignaturanforderungen

Einige Anwendungsfunktionen erfordern eine besondere Art von Vorgangssignatur. Die NetMsmqBinding-Bindung unterstützt beispielsweise permanente Dienste und Clients, in denen eine Anwendung während der Kommunikation neu gestartet und ohne Meldungsverlust genau dort fortgesetzt werden kann, wo sie angehalten wurde. (Weitere Informationen finden Sie unter Warteschlangen in Windows Communication Foundation.) Permanente Vorgänge dürfen allerdings nur einen einzelnen in-Parameter verwenden und haben keinen Rückgabewert.

Ein anderes Beispiel ist die Verwendung von Stream-Typen in Vorgängen. Da der Stream-Parameter den gesamten Textinhalt einschließt, muss es sich bei einer Ein- oder Ausgabe mit den Parametern ref, out oder einem Rückgabewert vom Typ Stream um die einzigen im Vorgang angegebenen Ein- und Ausgaben handeln. Außerdem muss es sich bei dem Parameter oder dem Rückgabetyp um Stream, System.ServiceModel.Channels.Message oder System.Xml.Serialization.IXmlSerializable handeln. Weitere Informationen zu Datenströmen finden Sie unter Umfangreiche Daten und Streaming.

Namen, Namespaces und Obfuskation

Die Namen und Namespaces der .NET-Typen in der Definition von Verträgen und Vorgängen sind wichtig, wenn Verträge in WSDL konvertiert und wenn Vertragsnachrichten erstellt und gesendet werden. Aus diesem Grund sollten Namen und Namespaces von Verträgen unbedingt explizit mithilfe der Name- und der Namespace-Eigenschaft aller unterstützenden Vertragsattribute (wie ServiceContractAttribute, OperationContractAttribute, DataContractAttribute, DataMemberAttribute und anderer Vertragsattribute) festgelegt werden.

Sind die Namen und Namespaces nicht explizit festgelegt, verändert die Verwendung der IL-Obfuskation für die Assembly die Namen und Namespaces des Vertragstyps. Dadurch ergeben sich Änderungen beim WSDL- und Übertragungsaustausch, wodurch üblicherweise Fehler auftreten. Wenn Sie die Vertragsnamen und -Namespaces nicht explizit festlegen, aber dennoch die Obfuskation verwenden möchten, unterbinden Sie Änderungen an den Namen und Namespaces des Vertragstyps mithilfe des ObfuscationAttribute-Attributs und des ObfuscateAssemblyAttribute-Attributs.

Siehe auch