Erstellen einen benutzerdefinierten Header, signiert und- oder verschlüsselteCreating a custom header that is signed and-or encrypted

Beim Aufrufen eines Nicht-WCF-Dienstes mit einem WCF-Client müssen in einigen Fällen benutzerdefinierte SOAP-Header verwendet werden.When calling a non-WCF service using a WCF client it is sometimes necessary to use custom SOAP headers. In WCF ist ein Kanonisierungsfehler vorhanden, der verhindert, dass signierte und verschlüsselte benutzerdefinierte Header mit einem Nicht-WCF-Dienst verwendet werden können.There is a canonicalization bug in WCF that prevents custom headers that are signed and encrypted from working with a non-WCF service. Dieses Problem wird durch die inkorrekte Kanonisierung von XML-Standardnamespaces verursacht.The problem is caused by the incorrect canonicalization of default XML namespaces. Es ist jedoch nur problematisch, wenn Nicht-WCF-Dienste mit benutzerdefinierten Headern aufgerufen werden, die signiert und/oder verschlüsselt sind.This is only problematic when calling non-WCF services with custom headers that are signed and/or encrypted. Wenn der Dienst die Nachricht mit dem signierten und/oder verschlüsselten benutzerdefinierten Header empfängt, kann er die Signatur nicht verifizieren.When the service receives the message containing the signed and/or encrypted custom header it is unable to verify the signature. Mit der folgenden Problemumgehung wird der Kanonisierungsfehler vermieden, und die Interoperabilität mit Nicht-WCF-Diensten wird ermöglicht. Die Interoperabilität mit WCF-Diensten wird dabei jedoch nicht beeinträchtigt.This workaround avoids the canonicalization bug, allows interoperability with non-WCF services, but does not prevent interoperability with WCF services.

Definieren des benutzerdefinierten HeadersDefining the custom header

Benutzerdefinierte Header werden definiert, indem ein Nachrichtenvertrag festgelegt wird und die als Header zu sendenden Member mit einem MessageHeaderAttribute-Attribut markiert werden.Custom headers are defined by defining a message contract and marking the members you want to be sent as headers with a MessageHeaderAttribute attribute. Zur Umgehung des Kanonisierungsfehlers müssen Sie sicherstellen, dass das XML-Serialisierungsprogramm den Namespace für den benutzerdefinierten Header mit einem Präfix deklariert und nicht die Standardnamespacedeklaration verwendet.To work around the canonicalization bug you must ensure that the XML serializer declares the namespace for the custom header with a prefix instead of a default namespace declaration. Im folgenden Code wird veranschaulicht, wie der Datentyp für den Nachrichtenheader mit einer korrekten Namespacedeklaration definiert wird.The following code shows how to define the data type that will be used as a message header with the correct namespace declaration.

[System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil", "3.0.4506.648")]  
[System.SerializableAttribute()]  
[System.Diagnostics.DebuggerStepThroughAttribute()]  
[System.ComponentModel.DesignerCategoryAttribute("code")]  
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://www.example.org/getMessage/")]  
public partial class msgHeaderElement  
{  
   // Define the XML namespace and force it to use an ‘h’ prefix  
    [System.Xml.Serialization.XmlNamespaceDeclarations]  
    public System.Xml.Serialization.XmlSerializerNamespaces _xsns = new System.Xml.Serialization.XmlSerializerNamespaces(new System.Xml.XmlQualifiedName[] { new System.Xml.XmlQualifiedName("h", "http://www.example.org/getMessage/") });  

    private string msgHeaderInputField;  
  [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=0)]  
    public string msgHeaderInput  
    {  
        get  
        {  
            return this.msgHeaderInputField;  
        }  
        set  
        {  
            this.msgHeaderInputField = value;  
        }  
    }  
}  

In diesem Code wird der neue Typ msgHeaderElement deklariert, der mit dem XML-Serialisierungsprogramm serialisiert wird.This code declares a new type called msgHeaderElement that will be serialized with the XML Serializer. Beim Serialisieren einer Instanz dieses Typs wird ein Namespace mit dem Präfix 'h' definiert, wodurch der Kanonisierungsfehler umgangen wird.When an instance of this type is serialized, it will define a namespace with an ‘h’ prefix, thus working around the canonicalization bug. Im Nachrichtenvertrag wird dann eine Instanz von msgHeaderElement definiert, die mit dem MessageHeaderAttribute-Attribut markiert wird, wie im folgenden Beispiel veranschaulicht.The message contract would then define an instance of msgHeaderElement and mark it with the MessageHeaderAttribute attribute as shown in the following example.

[MessageContract]  
public  class MyMessageContract  
{  
   // other message contents...  
   [MessageHeader(ProductionLevel=ProtectionLevel.EncryptAndSign)]  
   public msgHeaderElement;  
   // other message contents...  
}  

Siehe auchSee Also

StandardnachrichtenvertragDefault Message Contract
NachrichtenverträgeMessage Contracts
Verwenden von NachrichtenverträgenUsing Message Contracts