Verwenden der Message-KlasseUsing the Message Class

Die Message Klasse ist von grundlegender Wichtigkeit, Windows Communication Foundation (WCF).The Message class is fundamental to Windows Communication Foundation (WCF). Die gesamte Kommunikation zwischen Clients und Diensten führt letztlich zu gesendeten und empfangenen Message-Instanzen.All communication between clients and services ultimately results in Message instances being sent and received.

Sie würden normalerweise nicht direkt mit der Message-Klasse interagieren.You would not usually interact with the Message class directly. Stattdessen werden WCF Service Model-Konstrukten wie Datenverträge, Nachrichtenverträge und Vorgangsverträge zum Beschreiben von ein- und ausgehender Nachrichten verwendet.Instead, WCF service model constructs, such as data contracts, message contracts, and operation contracts, are used to describe incoming and outgoing messages. In einigen komplexen Szenarien können Sie jedoch direkt mit der Message-Klasse programmieren.However, in some advanced scenarios you can program using the Message class directly. Die Verwendung der Message-Klasse kann beispielsweise in den folgenden Fällen erforderlich sein:For example, you might want to use the Message class:

  • Wenn Sie eine alternative Methode zum Erstellen des Inhalts ausgehender Nachrichten (z. B. Erstellen einer Nachricht direkt aus einer Datei auf der Festplatte) statt des Serialisierens von .NET Framework.NET Framework-Objekten benötigen.When you need an alternative way of creating outgoing message contents (for example, creating a message directly from a file on disk) instead of serializing .NET Framework.NET Framework objects.

  • Wenn Sie eine alternative Methode zum Verwenden des Inhalts eingehender Nachrichten (z. B. zum Anwenden einer XSLT-Transformation auf den unformatierten XML-Inhalt) statt des Deserialisierens in .NET Framework.NET Framework-Objekte benötigen.When you need an alternative way of using incoming message contents (for example, when you want to apply an XSLT transformation to the raw XML contents) instead of deserializing into .NET Framework.NET Framework objects.

  • Wenn Sie Nachrichten allgemein und unabhängig vom Nachrichteninhalt bearbeiten müssen (z. B. zum Routen oder Weiterleiten von Nachrichten beim Erstellen eines Routers, Lastenausgleichsmoduls oder Veröffentlichen-Abonnieren-Systems).When you need to deal with messages in a general way regardless of message contents (for example, when routing or forwarding messages when building a router, load-balancer, or a publish-subscribe system).

Vor der Verwendung der Message Klasse, die WCF Data Transfer-Architektur in Kennenlernen Übersicht über die Architektur von Data Transfer.Before using the Message class, familiarize yourself with the WCF data transfer architecture in Data Transfer Architectural Overview.

Eine Message ist ein Allzweckcontainer für Daten, ihr Design folgt aber eng dem Design einer Nachricht im SOAP-Protokoll.A Message is a general-purpose container for data, but its design closely follows the design of a message in the SOAP protocol. Wie in SOAP verfügt eine Nachricht über einen Nachrichtentext und einen Header.Just like in SOAP, a message has both a message body and headers. Der Nachrichtentext enthält die tatsächlichen Nutzlastdaten, während die Header zusätzliche benannte Datencontainer enthalten.The message body contains the actual payload data, while the headers contain additional named data containers. Die Regeln für das Lesen und Schreiben von Text und Headern sind unterschiedlich, so werden die Header immer im Arbeitsspeicher gepuffert, und der Zugriff ist beliebig oft in beliebiger Reihenfolge möglich, während der Text nur einmal gelesen und in einem Stream übertragen werden kann.The rules for reading and writing the body and the headers are different, for example, the headers are always buffered in memory and may be accessed in any order any number of times, while the body may be read only once and may be streamed. Normalerweise werden in SOAP der Nachrichtentext dem SOAP-Text und die Nachrichtenheader den SOAP-Headern zugeordnet.Normally, when using SOAP, the message body is mapped to the SOAP body and the message headers are mapped to the SOAP headers.

Verwenden der Meldungsklasse in VorgängenUsing the Message Class in Operations

Sie können die Message-Klasse als Eingabeparameter eines Vorgangs, als den Rückgabewert eines Vorgangs oder beides verwenden.You can use the Message class as an input parameter of an operation, the return value of an operation, or both. Wenn Message an einer Stelle in einem Vorgang verwendet wird, gelten die folgenden Einschränkungen:If Message is used anywhere in an operation, the following restrictions apply:

  • Der Vorgang kann über keinen out-Parameter oder ref-Parameter verfügen.The operation cannot have any out or ref parameters.

  • Es kann nicht mehr als einen input-Parameter geben.There cannot be more than one input parameter. Wenn der Parameter vorhanden ist, muss er entweder eine Nachricht oder ein Nachrichtenvertragstyp sein.If the parameter is present, it must be either Message or a message contract type.

  • Der Rückgabetyp muss entweder void, Message oder ein Nachrichtenvertragstyp sein.The return type must be either void, Message, or a message contract type.

Das folgende Codebeispiel enthält einen gültigen Vorgangsvertrag.The following code example contains a valid operation contract.

[ServiceContract]
public interface IMyService
{
    [OperationContract]
    Message GetData();

    [OperationContract]
    void PutData(Message m);
}
<ServiceContract()>  _
Public Interface IMyService
    <OperationContract()>  _
    Function GetData() As Message 
    
    <OperationContract()>  _
    Sub PutData(ByVal m As Message) 
End Interface

Erstellen grundlegender NachrichtenCreating Basic Messages

Die Message-Klasse stellt statische CreateMessage-Factorymethoden bereit, mit denen Sie grundlegende Nachrichten erstellen können.The Message class provides static CreateMessage factory methods that you can use to create basic messages.

Alle CreateMessage-Überladungen nehmen einen Versionsparameter vom Typ MessageVersion an, der die für die Nachricht zu verwendende SOAP-Version und Version der WS-Adressierung angibt.All CreateMessage overloads take a version parameter of type MessageVersion that indicates the SOAP and WS-Addressing versions to use for the message. Wenn Sie die gleichen Protokollversionen wie die eingehende Nachricht verwenden möchten, können Sie die IncomingMessageVersion-Eigenschaft auf der OperationContext-Instanz nutzen, die aus der Current-Eigenschaft abgerufen wurde.If you want to use the same protocol versions as the incoming message, you can use the IncomingMessageVersion property on the OperationContext instance obtained from the Current property. Die meisten CreateMessage-Überladungen haben außerdem einen Zeichenfolgenparameter, der die für die Nachricht zu verwendende SOAP-Aktion angibt.Most CreateMessage overloads also have a string parameter that indicates the SOAP action to use for the message. Die Version kann auf None festgelegt werden, um die Generierung des SOAP-Umschlags zu deaktivieren; die Nachricht besteht nur aus dem Text.Version can be set to None to disable SOAP envelope generation; the message consists of only the body.

Erstellen von Nachrichten aus ObjektenCreating Messages from Objects

Die grundlegendste CreateMessage-Überladung, die nur eine Version und eine Aktion annimmt, erstellt eine Nachricht, die keinen Text enthält.The most basic CreateMessage overload that takes only a version and an action creates a message with an empty body. Eine weitere Überladung nimmt einen zusätzlichen Object-Parameter an; es wird eine Nachricht erstellt, deren Text die serialisierte Darstellung des entsprechenden Objekts ist.Another overload takes an additional Object parameter; this creates a message whose body is the serialized representation of the given object. Verwenden Sie das DataContractSerializer mit Standardeinstellungen für die Serialisierung.Use the DataContractSerializer with default settings for serialization. Wenn Sie ein anderes Serialisierungsprogramm verwenden möchten oder das DataContractSerializer anders konfiguriert werden soll, verwenden Sie die CreateMessage-Überladung, die auch einen XmlObjectSerializer-Parameter annimmt.If you want to use a different serializer, or you want the DataContractSerializer configured differently, use the CreateMessage overload that also takes an XmlObjectSerializer parameter.

Sie können z. B. zum Zurückgeben eines Objekts in einer Nachricht den folgenden Code verwenden.For example, to return an object in a message, you can use the following code.

public class MyService1 : IMyService
{
    public Message GetData()
    {
        Person p = new Person();
        p.name = "John Doe";
        p.age = 42;
        MessageVersion ver = OperationContext.Current.IncomingMessageVersion;
        return Message.CreateMessage(ver, "GetDataResponse", p);
    }

    public void PutData(Message m)
    {
        // Not implemented.
    }
}
[DataContract]
public class Person
{
    [DataMember] public string name;
    [DataMember] public int age;
}
Public Class MyService1
    Implements IMyService
    
    Public Function GetData() As Message _
     Implements IMyService.GetData
        Dim p As New Person()
        p.name = "John Doe"
        p.age = 42
        Dim ver As MessageVersion = _
          OperationContext.Current.IncomingMessageVersion
        Return Message.CreateMessage(ver, "GetDataResponse", p)

    End Function
    
    
    Public Sub PutData(ByVal m As Message) _
    Implements IMyService.PutData
        ' Not implemented.
    End Sub
End Class
<DataContract()>  _
Public Class Person
    <DataMember()>  _
    Public name As String
    <DataMember()>  _
    Public age As Integer
End Class

Erstellen von Nachrichten aus XML-LesernCreating Messages from XML Readers

Bestimmte CreateMessage-Überladungen nehmen einen XmlReader oder einen XmlDictionaryReader für den Text anstelle eines Objekts an.There are CreateMessage overloads that take an XmlReader or an XmlDictionaryReader for the body instead of an object. In diesem Fall enthält der Text der Nachricht die XML, die aus dem Lesen des übergebenen XML-Readers resultiert.In this case, the body of the message contains the XML that results from reading from the passed XML reader. Der folgende Code gibt beispielsweise eine Nachricht mit aus einer XML-Datei gelesenem Textinhalt zurück:For example, the following code returns a message with body contents read from an XML file.

public class MyService2 : IMyService
{
    public Message GetData()
    {
        FileStream stream = new FileStream("myfile.xml",FileMode.Open);
        XmlDictionaryReader xdr =
               XmlDictionaryReader.CreateTextReader(stream, 
                           new XmlDictionaryReaderQuotas());
        MessageVersion ver = 
            OperationContext.Current.IncomingMessageVersion;
        return Message.CreateMessage(ver,"GetDataResponse",xdr);
    }

    public void PutData(Message m)
    {
        // Not implemented.
    }

}
Public Class MyService2
    Implements IMyService
    
    Public Function GetData() As Message Implements IMyService.GetData
        Dim stream As New FileStream("myfile.xml", FileMode.Open)
        Dim xdr As XmlDictionaryReader = _
        XmlDictionaryReader.CreateTextReader(stream, New XmlDictionaryReaderQuotas())
        Dim ver As MessageVersion = OperationContext.Current.IncomingMessageVersion
        Return Message.CreateMessage(ver, "GetDataResponse", xdr)

    End Function
    
    
    Public Sub PutData(ByVal m As Message) Implements IMyService.PutData

    End Sub
End Class

Darüber hinaus gibt es CreateMessage-Überladungen, die einen XmlReader oder einen XmlDictionaryReader annehmen, der die gesamte Nachricht und nicht nur den Text darstellt.Additionally, there are CreateMessage overloads that take an XmlReader or an XmlDictionaryReader that represents the entire message and not just the body. Diese Überladungen nehmen auch einen ganzzahligen maxSizeOfHeaders-Parameter an.These overloads also take an integer maxSizeOfHeaders parameter. Header werden immer in den Arbeitsspeicher gepuffert, sobald die Nachricht erstellt wurde, und dieser Parameter begrenzt die stattfindende Pufferung.Headers are always buffered into memory as soon as the message is created, and this parameter limits the amount of buffering that takes place. Dieser Parameter sollte auf einen sicheren Wert festgelegt werden, wenn die XML von einer nicht vertrauenswürdigen Quelle stammt, um einen möglichen Denial-of-Service-Angriff zu vermeiden.It is important to set this parameter to a safe value if the XML is coming from an untrusted source to mitigate the possibility of a denial of service attack. Die SOAP-Version und die Version der WS-Adressierung der Nachricht, die der XML-Leser darstellt, müssen mit den durch den Versionsparameter angegebenen Versionen übereinstimmen.The SOAP and WS-Addressing versions of the message the XML reader represents must match the versions indicated using the version parameter.

Erstellen von Nachrichten mit dem Body Writer-ObjektCreating Messages with BodyWriter

Eine CreateMessage-Überladung nimmt eine BodyWriter-Instanz an, um den Text der Nachricht zu beschreiben.One CreateMessage overload takes a BodyWriter instance to describe the body of the message. Ein BodyWriter ist eine abstrakte Klasse, die abgeleitet werden kann, um das Erstellen von Nachrichtentexten anzupassen.A BodyWriter is an abstract class that can be derived to customize how message bodies are created. Sie können eine eigene abgeleitete BodyWriter-Klasse erstellen, um Nachrichtentexte benutzerdefiniert zu beschreiben.You can create your own BodyWriter derived class to describe message bodies in a custom way. Sie müssen die BodyWriter.OnWriteBodyContents-Methode überschreiben, die einen XmlDictionaryWriter annimmt; diese Methode ist für das Schreiben des Textes zuständig.You must override the BodyWriter.OnWriteBodyContents method that takes an XmlDictionaryWriter; this method is responsible for writing out the body.

Body Writer-Objekte können gepuffert oder nicht gepuffert (gestreamt) sein.Body writers can be buffered or non-buffered (streamed). Gepufferte Body Writer-Objekte schreiben ihren Inhalt beliebig oft, während gestreamte Objekte den Inhalt nur einmal schreiben können.Buffered body writers can write out their contents any number of times, while streamed ones can write out their contents only once. Die IsBuffered-Eigenschaft gibt an, ob ein Body Writer-Objekt gepuffert ist oder nicht.The IsBuffered property indicates whether a body writer is buffered or not. Sie können dies für das Body Writer-Objekt festlegen, indem Sie den geschützten BodyWriter-Konstruktor aufrufen, der einen booleschen isBuffered-Parameter annimmt.You can set this for your body writer by calling the protected BodyWriter constructor that takes an isBuffered boolean parameter. Body Writer-Objekte unterstützen das Erstellen eines gepufferten Body Writer-Objekts aus einem nicht gepufferten Body Writer-Objekt.Body writers support creating a buffered body writer from a non-buffered body writer. Sie können die OnCreateBufferedCopy-Methode überschreiben, um diesen Prozess anzupassen.You can override the OnCreateBufferedCopy method to customize this process. Standardmäßig wird ein Speicherpuffer verwendet, der das von OnWriteBodyContents zurückgegebene XML enthält.By default, an in-memory buffer that contains the XML returned by OnWriteBodyContents is used. OnCreateBufferedCopy akzeptiert einen ganzzahligen maxBufferSize-Parameter. Wenn Sie diese Methode überschreiben, dürfen Sie keine Puffer erstellen, die diese maximale Größe überschreiten.OnCreateBufferedCopy takes a maxBufferSize integer parameter; if you override this method, you must not create buffers larger than this maximum size.

Die BodyWriter-Klasse bietet die WriteBodyContents-Methode und die CreateBufferedCopy-Methode, die im Grunde einfache Wrapper um die OnWriteBodyContents-Methode bzw. die OnCreateBufferedCopy-Methode sind.The BodyWriter class provides the WriteBodyContents and CreateBufferedCopy methods, which are essentially thin wrappers around OnWriteBodyContents and OnCreateBufferedCopy methods, respectively. Diese Methoden führen eine Zustandsprüfung durch, um sicherzustellen, dass auf ein nicht gepuffertes Body Writer-Objekt höchstens einmal zugegriffen wird.These methods perform state checking to ensure that a non-buffered body writer is not accessed more than once. Diese Methoden werden nur direkt aufgerufen, wenn benutzerdefinierte abgeleitete Message-Klassen erstellt werden, die auf BodyWriters basieren.These methods are called directly only when creating custom Message derived classes based on BodyWriters.

Erstellen von FehlermeldungenCreating Fault Messages

Sie können bestimmte CreateMessage-Überladungen verwenden, um SOAP-Fehlermeldungen zu erstellen.You can use certain CreateMessage overloads to create SOAP fault messages. Die grundlegendste dieser Überladungen nimmt ein MessageFault-Objekt an, das den Fehler beschreibt.The most basic of these takes a MessageFault object that describes the fault. Andere Überladungen werden aus Gründen der Benutzerfreundlichkeit bereitgestellt.Other overloads are provided for convenience. Die erste solcher Überladungen nimmt einen FaultCode und eine Zeichenfolge der Ursache an und erstellt einen MessageFault mit MessageFault.CreateFault unter Verwendung dieser Informationen.The first such overload takes a FaultCode and a reason string and creates a MessageFault using MessageFault.CreateFault using this information. Die andere Überladung nimmt eine Detailobjekt an und übergibt es auch zusammen mit dem Fehlercode und der Ursache an CreateFault.The other overload takes a detail object and also passes it to CreateFault together with the fault code and the reason. So gibt beispielsweise der folgende Vorgang einen Fehler zurück:For example, the following operation returns a fault.

public class MyService3 : IMyService
{
    public Message GetData()
    {
        FaultCode fc = new FaultCode("Receiver");
        MessageVersion ver = OperationContext.Current.IncomingMessageVersion;
            return Message.CreateMessage(ver,fc,"Bad data","GetDataResponse");
    }

    public void PutData(Message m)
    {
        // Not implemented.
    }       
}
Public Class MyService3
    Implements IMyService

    Public Function GetData() As Message Implements IMyService.GetData
        Dim fc As New FaultCode("Receiver")
        Dim ver As MessageVersion = OperationContext.Current.IncomingMessageVersion
        Return Message.CreateMessage(ver, fc, "Bad data", "GetDataResponse")

    End Function


    Public Sub PutData(ByVal m As Message) Implements IMyService.PutData

    End Sub
End Class

Extrahieren von NachrichtentextdatenExtracting Message Body Data

Die Message-Klasse unterstützt mehrere Methoden zum Extrahieren von Informationen aus dem Text.The Message class supports multiple ways of extracting information from its body. Diese können in die folgenden Kategorien klassifiziert werden:These can be classified into the following categories:

  • Einmaliges Abrufen des gesamten Nachrichtentexts in einen XML-Writer.Getting the entire message body written out at once to an XML writer. Dies wird als bezeichnet Schreiben einer Nachricht.This is referred to as writing a message.

  • Laufenlassen eines XML-Readers über den Nachrichtentext.Getting an XML reader over the message body. Dies ermöglicht es Ihnen, später nach Bedarf Stück für Stück auf den Nachrichtentext zuzugreifen.This enables you to later access the message body piece-by-piece as required. Dies wird als bezeichnet Lesen einer Nachricht.This is referred to as reading a message.

  • Die gesamte Nachricht, einschließlich des Texts, kann in einen Puffer im Arbeitsspeicher vom MessageBuffer-Typ kopiert werden.The entire message, including its body, can be copied to an in-memory buffer of the MessageBuffer type. Dies wird als bezeichnet Kopieren einer Nachricht.This is referred to as copying a message.

Sie können unabhängig von der Zugriffsmethode nur einmal auf den Text einer Message zugreifen.You can access the body of a Message only once, regardless of how it is accessed. Ein Nachrichtenobjekt verfügt über eine State-Eigenschaft, die anfänglich auf "Erstellt" festgelegt ist.A message object has a State property, which is initially set to Created. Mit den drei zuvor beschriebenen Zugriffsmethoden wird der Zustand auf "Geschrieben", "Gelesen" bzw. "Kopiert" festgelegt.The three access methods described in the preceding list set the state to Written, Read, and Copied, respectively. Darüber hinaus kann eine Close-Methode den Zustand auf "Geschlossen" festlegen, wenn der Inhalt des Nachrichtentexts nicht mehr benötigt wird.Additionally, a Close method can set the state to Closed when the message body contents are no longer required. Auf den Nachrichtentext kann nur im Zustand "Erstellt" zugegriffen werden, und eine Rückkehr zu diesem Zustand ist nach einer Zustandsänderung nicht mehr möglich.The message body can be accessed only in the Created state, and there is no way to go back to the Created state after the state has changed.

Schreiben von NachrichtenWriting Messages

Die WriteBodyContents(XmlDictionaryWriter)-Methode schreibt den Inhalt des Texts einer bestimmten Message-Instanz in einen angegebenen XML-Writer.The WriteBodyContents(XmlDictionaryWriter) method writes out the body contents of a given Message instance to a given XML writer. Die WriteBody-Methode führt den gleichen Vorgang aus. Einziger Unterschied: Der Textinhalt wird in ein entsprechendes Wrapperelement eingeschlossen (beispielsweise <soap:body>).The WriteBody method does the same, except that it encloses the body contents in the appropriate wrapper element (for example, <soap:body>). Schließlich schreibt WriteMessage die ganze Nachricht, einschließlich des umfassenden SOAP-Umschlags und der Header.Finally, WriteMessage writes out the entire message, including the wrapping SOAP envelope and the headers. Bei deaktiviertem SOAP (Version ist MessageVersion.None) wird von allen drei Methoden der gleiche Vorgang ausgeführt: Der Inhalt des Nachrichtentexts wird geschrieben.If SOAP is turned off (Version is MessageVersion.None), all three methods do the same thing: they write out the message body contents.

Beispielsweise schreibt der folgende Code der Text einer eingehenden Nachricht in eine Datei.For example, the following code writes out the body of an incoming message to a file.

public class MyService4 : IMyService
{
    public void PutData(Message m)
    {
        FileStream stream = new FileStream("myfile.xml",FileMode.Create);
        XmlDictionaryWriter xdw =
            XmlDictionaryWriter.CreateTextWriter(stream);
        m.WriteBodyContents(xdw);
        xdw.Flush();
    }

    public Message GetData()
    {
        throw new NotImplementedException();
    }
}
Public Class MyService4
    Implements IMyService
    
    Public Sub PutData(ByVal m As Message) Implements IMyService.PutData
        Dim stream As New FileStream("myfile.xml", FileMode.Create)
        Dim xdw As XmlDictionaryWriter = XmlDictionaryWriter.CreateTextWriter(stream)
        m.WriteBodyContents(xdw)
        xdw.Flush()

    End Sub
    
    
    Public Function GetData() As Message Implements IMyService.GetData
        Throw New NotImplementedException()

    End Function
End Class

Zwei zusätzliche Hilfsmethoden schreiben bestimmte SOAP-Startelement-Tags.Two additional helper methods write out certain SOAP start element tags. Diese Methoden haben keinen Zugriff auf den Nachrichtentext, der Nachrichtenzustand wird also nicht geändert.These methods do not access the message body and so they do not change the message state. Dazu gehören:These include:

Rufen Sie zum Schreiben der jeweiligen Endelement-Tags WriteEndElement auf dem entsprechenden XML-Writer auf.To write the corresponding end element tags, call WriteEndElement on the corresponding XML writer. Diese Methoden werden selten direkt aufgerufen.These methods are rarely called directly.

Lesen von NachrichtenReading Messages

Die primäre Methode zum Lesen eines Nachrichtentexts ist das Aufrufen von GetReaderAtBodyContents.The primary way to read a message body is to call GetReaderAtBodyContents. Ein XmlDictionaryReader wird zurückgegeben, mit dem Sie den Nachrichtentext lesen können.You get back an XmlDictionaryReader that you can use to read the message body. Beachten Sie, dass die Message in den Zustand "Gelesen" übergeht, sobald GetReaderAtBodyContents aufgerufen wird, und nicht, wenn Sie den XML-Reader verwenden.Note that the Message transitions to the Read state as soon as GetReaderAtBodyContents is called, and not when you use the returned XML reader.

Die GetBody-Methode ermöglicht Ihnen auch den Zugriff auf den Nachrichtentext als typisiertes Objekt.The GetBody method also enables you to access the message body as a typed object. Intern verwendet diese Methode GetReaderAtBodyContents, daher geht die Nachricht auch in den Read-Zustand über (siehe die State-Eigenschaft).Internally, this method uses GetReaderAtBodyContents, and so it also transitions the message state to the Read state (see the State property).

Es wird empfohlen, die IsEmpty-Eigenschaft zu überprüfen, wobei in diesem Fall die Nachricht keinen Text enthält und GetReaderAtBodyContents eine InvalidOperationException auslöst.It is good practice to check the IsEmpty property, in which case the message body is empty and GetReaderAtBodyContents throws an InvalidOperationException. Wenn es sich um eine empfangene Nachricht handelt (beispielsweise um die Antwort), sollten Sie auch IsFault überprüfen, wodurch angegeben wird, ob die Nachricht einen Fehler enthält.Also, if it is a received message (for example, the reply), you may also want to check IsFault, which indicates whether the message contains a fault.

Die grundlegendste Überladung von GetBody deserialisiert den Nachrichtentext in eine Instanz eines Typs (angegeben durch den generischen Parameter) unter Verwendung eines DataContractSerializer, konfiguriert mit den Standardeinstellungen und mit deaktiviertem MaxItemsInObjectGraph-Kontingent.The most basic overload of GetBody deserializes the message body into an instance of a type (indicated by the generic parameter) using a DataContractSerializer configured with the default settings and with the MaxItemsInObjectGraph quota disabled. Wenn Sie ein anderes Serialisierungsmodul verwenden oder das DataContractSerializer nicht standardmäßig konfigurieren möchten, verwenden Sie die GetBody-Überladung, die ein XmlObjectSerializer annimmt.If you want to use a different serialization engine, or configure the DataContractSerializer in a non-default way, use the GetBody overload that takes an XmlObjectSerializer.

Der folgende Code extrahiert beispielsweise Daten aus einem Nachrichtentext, der ein serialisiertes Person-Objekt enthält, und gibt den Namen der Person aus.For example, the following code extracts data from a message body that contains a serialized Person object and prints out the person’s name.

    public class MyService5 : IMyService
    {
        public void PutData(Message m)
        {
            Person p = m.GetBody<Person>();
            Console.WriteLine(p.name);
        }

        public Message GetData()
        {
            throw new NotImplementedException();
        }
      
    }
}
namespace Samples2
{
    [ServiceContract]
    public interface IMyService
    {
        [OperationContract]
        Message GetData();

        [OperationContract]
        void PutData(Message m);
    }

    [DataContract]
    public class Person
    {
        [DataMember] public string name;
        [DataMember] public int age;
    }
    Public Class MyService5
        Implements IMyService

        Public Sub PutData(ByVal m As Message) Implements IMyService.PutData
            Dim p As Person = m.GetBody(Of Person)()
            Console.WriteLine(p.name)

        End Sub


        Public Function GetData() As Message Implements IMyService.GetData
            Throw New NotImplementedException()

        End Function
    End Class
End Namespace
Namespace Samples2
    <ServiceContract()>  _
    Public Interface IMyService
        <OperationContract()>  _
        Function GetData() As Message 
        
        <OperationContract()>  _
        Sub PutData(ByVal m As Message) 
    End Interface

    <DataContract()>  _
    Public Class Person
        <DataMember()>  _
        Public name As String
        <DataMember()>  _
        Public age As Integer
    End Class

Kopieren einer Nachricht in einen PufferCopying a Message into a Buffer

Manchmal ist es erforderlich, mehrmals auf den Nachrichtentext zuzugreifen, beispielsweise um die gleiche Nachricht an mehrere Ziele als Teil eines Verleger-Abonnent-Systems weiterzuleiten.Sometimes it is necessary to access the message body more than once, for example, to forward the same message to multiple destinations as part of a publisher-subscriber system. In diesem Fall ist es notwendig, die gesamte Nachricht (einschließlich des Textes) im Arbeitsspeicher zu puffern.In this case, it is necessary to buffer the entire message (including the body) in memory. Sie können dazu CreateBufferedCopy(Int32) aufrufen.You can do this by calling CreateBufferedCopy(Int32). Diese Methode nimmt einen ganzzahligen Parameter an, der die maximale Puffergröße darstellt, und erstellt einen Puffer mit maximal dieser Größe.This method takes an integer parameter that represents the maximum buffer size, and creates a buffer not larger than this size. Legen Sie dafür einen sicheren Wert fest, wenn die Nachricht von einer nicht vertrauenswürdigen Quelle stammt.It is important to set this to a safe value if the message is coming from an untrusted source.

Der Puffer wird als MessageBuffer-Instanz zurückgegeben.The buffer is returned as a MessageBuffer instance. Es gibt mehrere Möglichkeiten, um auf Daten im Puffer zuzugreifen.You can access data in the buffer in several ways. Die primäre Methode ist, CreateMessage aufzurufen, um Message-Instanzen aus dem Puffer zu erstellen.The primary way is to call CreateMessage to create Message instances from the buffer.

Eine weitere Methode ist das Implementieren der IXPathNavigable-Schnittstelle, die die MessageBuffer-Klasse implementiert, um direkt auf die zugrunde liegende XML zuzugreifen.Another way to access the data in the buffer is to implement the IXPathNavigable interface that the MessageBuffer class implements to access the underlying XML directly. Einige CreateNavigator-Überladungen ermöglichen das Erstellen von durch ein Knotenkontingent geschützten System.Xml.XPath-Navigatoren, die die Anzahl der aufrufbaren XML-Knoten beschränken.Some CreateNavigator overloads allow you to create System.Xml.XPath navigators protected by a node quota, limiting the number of XML nodes that can be visited. Dies hilft, Denial-of-Service-Angriffe auf der Grundlage von längerer Verarbeitungszeit zu verhindern.This helps prevent denial of service attacks based on lengthy processing time. Dieses Kontingent ist standardmäßig deaktiviert.This quote is disabled by default. Mit einigen CreateNavigator-Überladungen können Sie angeben, wie viele Leerstellen in der XML mit der XmlSpace-Enumeration behandelt werden soll, wobei der Standard XmlSpace.None ist.Some CreateNavigator overloads allow you to specify how white space should be handled in the XML using the XmlSpace enumeration, with the default being XmlSpace.None.

Die letzte Methode zum Zugreifen auf den Inhalt eines Nachrichtenpuffers ist das Schreiben des Inhalts in einen Stream mit WriteMessage.A final way to access the contents of a message buffer is to write out its contents to a stream using WriteMessage.

Das folgende Beispiel demonstriert das Arbeiten mit einem MessageBuffer: Eine eingehende Nachricht wird an mehrere Empfänger weitergeleitet und anschließend in einer Datei protokolliert.The following example demonstrates the process of working with a MessageBuffer: an incoming message is forwarded to multiple recipients, and then logged to a file. Ohne Pufferung ist dies nicht möglich, da dann der Zugriff auf den Nachrichtentext nur einmal möglich ist.Without buffering, this is not possible, because the message body can then be accessed only once.

[ServiceContract]
public class ForwardingService
{
    private List<IOutputChannel> forwardingAddresses;

    [OperationContract]
    public void ForwardMessage (Message m)
    {
        //Copy the message to a buffer.
        MessageBuffer mb = m.CreateBufferedCopy(65536);
        
        //Forward to multiple recipients.
        foreach (IOutputChannel channel in forwardingAddresses)
        {
            Message copy = mb.CreateMessage();
            channel.Send(copy);
        }
        
        //Log to a file.
        FileStream stream = new FileStream("log.xml",FileMode.Append);
        mb.WriteMessage(stream);
        stream.Flush();
    }
}
<ServiceContract()>  _
Public Class ForwardingService
    Private forwardingAddresses As List(Of IOutputChannel)

    <OperationContract()> _
    Public Sub ForwardMessage(ByVal m As Message)
        'Copy the message to a buffer.
        Dim mb As MessageBuffer = m.CreateBufferedCopy(65536)

        'Forward to multiple recipients.
        Dim channel As IOutputChannel
        For Each channel In forwardingAddresses
            Dim copy As Message = mb.CreateMessage()
            channel.Send(copy)
        Next channel

        'Log to a file.
        Dim stream As New FileStream("log.xml", FileMode.Append)
        mb.WriteMessage(stream)
        stream.Flush()

    End Sub
End Class

Die MessageBuffer-Klasse verfügt über andere erwähnenswerte Member.The MessageBuffer class has other members worth noting. Die Close-Methode kann aufgerufen werden, um Ressourcen freizugeben, wenn der Pufferinhalt nicht mehr benötigt wird.The Close method can be called to free resources when the buffer contents are no longer required. Die BufferSize-Eigenschaft gibt die Größe des reservierten Puffers zurück.The BufferSize property returns the size of the allocated buffer. Die MessageContentType-Eigenschaft gibt den MIME-Inhaltstyp der Nachricht zurück.The MessageContentType property returns the MIME content type of the message.

Zugreifen auf den Nachrichtentext zum DebuggenAccessing the Message Body for Debugging

Zum Debuggen können Sie die ToString-Methode aufrufen, um eine Darstellung der Nachricht als Zeichenfolge abzurufen.For debugging purposes, you can call the ToString method to get a representation of the message as a string. Diese Darstellung stimmt im Allgemeinen mit der Darstellung einer Nachricht überein, wenn sie mit dem Textencoder codiert worden wäre, außer dass die XML zur Lesbarkeit besser formatiert wäre.This representation generally matches the way a message would look on the wire if it were encoded with the text encoder, except that the XML would be better formatted for human readability. Die einzige Ausnahme ist der Nachrichtentext.The one exception to this is the message body. Der Text kann nur einmal gelesen werden, und ToString ändert den Nachrichtenzustand nicht.The body can be read only once, and ToString does not change the message state. Aus diesem Grund die ToString Methode kann nicht in der Lage, den Text zugreifen und möglicherweise durch einen Platzhalter (z. B. "…" oder drei Punkte) statt im Nachrichtentext ersetzen.Therefore, the ToString method might not be able to access the body and might substitute a placeholder (for example, "…" or three dots) instead of the message body. Verwenden Sie deswegen ToString nicht zum Protokollieren von Nachrichten, wenn der Textinhalt der Nachrichten wichtig ist.Therefore, do not use ToString to log messages if the body content of the messages is important.

Zugreifen auf andere NachrichtenteileAccessing Other Message Parts

Für den Zugriff auf andere Informationen zur Nachricht als den Textinhalt werden verschiedene Eigenschaften bereitgestellt.Various properties are provided to access information about the message other than its body contents. Diese können jedoch nicht aufgerufen werden, wenn die Nachricht geschlossen wurde:However, these cannot be called once the message has been closed:

  • Die Headers-Eigenschaft stellt die Nachrichtenheader dar.The Headers property represents the message headers. Finden Sie im Abschnitt "Arbeiten mit Headern" weiter unten in diesem Thema.See the section on "Working with Headers" later in this topic.

  • Die Properties-Eigenschaft stellt die Eigenschaften der Nachricht dar, die Teile an die Nachricht angehängter benannter Daten sind, die beim Senden der Nachricht im Allgemeinen nicht ausgegeben werden.The Properties property represents the message properties, which are pieces of named data attached to the message that do not generally get emitted when the message is sent. Weitere Informationen finden Sie im Abschnitt "Arbeiten mit Eigenschaften" weiter unten in diesem Thema.See the section on "Working with Properties" later in this topic.

  • Die Version-Eigenschaft gibt die der Nachricht zugeordnete SOAP-Version und Version der WS-Adressierung an, oder None, wenn SOAP deaktiviert ist.The Version property indicates the SOAP and WS-Addressing version associated with the message, or None if SOAP is disabled.

  • Die IsFault-Eigenschaft gibt true zurück, wenn die Nachricht eine SOAP-Fehlermeldung ist.The IsFault property returns true if the message is a SOAP fault message.

  • Die IsEmpty-Eigenschaft gibt true zurück, wenn die Nachricht keinen Text enthält.The IsEmpty property returns true if the message is empty.

Sie können mithilfe der GetBodyAttribute(String, String)-Methode auf ein bestimmtes, mit einem bestimmten Namen und Namespace bezeichnetes Attribut im Textwrapperelement (z. B. <soap:Body>) zugreifen.You can use the GetBodyAttribute(String, String) method to access a particular attribute on the body wrapper element (for example, <soap:Body>) identified by a particular name and namespace. Wenn ein solches Attribut nicht gefunden wurde, wird null zurückgegeben.If such an attribute is not found, null is returned. Diese Methode kann nur dann aufgerufen werden, wenn sich die Message im Zustand "Erstellt" befindet (wenn noch nicht auf den Nachrichtentext zugegriffen wurde).This method can be called only when the Message is in the Created state (when the message body has not yet been accessed).

Arbeiten mit HeadernWorking with Headers

Ein Message darf eine beliebige Anzahl benannter XML-Fragmente aufgerufen Header.A Message can contain any number of named XML fragments, called headers. Jedes Fragment wird normalerweise einem SOAP-Header zugeordnet.Each fragment normally maps to a SOAP header. Der Zugriff auf Header erfolgt über die Headers-Eigenschaft des Typs MessageHeaders.Headers are accessed through the Headers property of type MessageHeaders. MessageHeaders ist eine Auflistung von MessageHeaderInfo-Objekten, und auf einzelne Header kann über die IEnumerable-Schnittstelle oder durch den Indexer zugegriffen werden.MessageHeaders is a collection of MessageHeaderInfo objects, and individual headers can be accessed through its IEnumerable interface or through its indexer. Im folgenden Code werden z. B. die Namen aller Header in einer Message aufgelistet.For example, the following code lists the names of all the headers in a Message.

public class MyService6 : IMyService
{
    public void PutData(Message m)
    {
        foreach (MessageHeaderInfo mhi in m.Headers)
        {
            Console.WriteLine(mhi.Name);
        }
    }

    public Message GetData()
    {
        throw new NotImplementedException();
    }
}
Public Class MyService6
    Implements IMyService

    Public Sub PutData(ByVal m As Message) Implements IMyService.PutData
        Dim mhi As MessageHeaderInfo
        For Each mhi In m.Headers
            Console.WriteLine(mhi.Name)
        Next mhi

    End Sub


    Public Function GetData() As Message Implements IMyService.GetData
        Throw New NotImplementedException()

    End Function
End Class

Hinzufügen, Entfernen und Suchen von HeadernAdding, Removing, Finding Headers

Sie können einen neuen Header am Ende aller vorhandenen Header mit der Add-Methode hinzufügen.You can add a new header at the end of all existing headers using the Add method. Sie können die Insert-Methode verwenden, um einen Header an einem bestimmten Index einzufügen.You can use the Insert method to insert a header at a particular index. Vorhandene Header werden für das eingefügte Element verschoben.Existing headers are shifted for the inserted item. Header werden nach ihrem Index geordnet, dabei ist der erste verfügbare Index 0.Headers are ordered according to their index, and the first available index is 0. Sie können mithilfe der verschiedenen CopyHeadersFrom-Methodenüberladungen Header aus einer anderen Message- oder MessageHeaders-Instanz hinzufügen.You can use the various CopyHeadersFrom method overloads to add headers from a different Message or MessageHeaders instance. Einige Überladungen kopieren einen einzelnen Header, während andere alle Header kopieren.Some overloads copy one individual header, while others copy all of them. Mit der Clear-Methode werden alle Header entfernt.The Clear method removes all headers. Die RemoveAt-Methode entfernt einen Header an einem bestimmten Index (alle nachfolgenden Header werden verschoben).The RemoveAt method removes a header at a particular index (shifting all headers after it). Die RemoveAll-Methode entfernt alle Header mit einem bestimmten Namen und Namespace.The RemoveAll method removes all headers with a particular name and namespace.

Rufen Sie mit der FindHeader-Methode einen bestimmten Header ab.Retrieve a particular header using the FindHeader method. Diese Methode nimmt den Namen und Namespace des zu suchenden Headers an, und gibt seinen Index zurück.This method takes the name and namespace of the header to find, and returns its index. Wenn der Header mehrmals auftritt, wird eine Ausnahme ausgelöst.If the header occurs more than once, an exception is thrown. Wenn der Header nicht gefunden wurde, wird -1 zurückgegeben.If the header is not found, it returns -1.

Im SOAP-Headermodell können Header einen Actor-Wert aufweisen, der den gewünschten Empfänger des Headers angibt.In the SOAP header model, headers can have an Actor value that specifies the intended recipient of the header. Die grundlegendste FindHeader-Überladung sucht nur Header, die für den letzten Empfänger der Nachricht vorgesehen sind.The most basic FindHeader overload searches only headers intended for the ultimate receiver of the message. Mit einer anderen Überladung können Sie jedoch angeben, welche Actor-Werte in der Suche enthalten sind.However, another overload enables you to specify which Actor values are included in the search. Weitere Informationen finden Sie in der SOAP-Spezifikation.For more information, see the SOAP specification.

Eine CopyTo(MessageHeaderInfo[], Int32)-Methode wird für das Kopieren von Headern aus einer MessageHeaders-Auflistung zu einem Array von MessageHeaderInfo-Objekten bereitgestellt.A CopyTo(MessageHeaderInfo[], Int32) method is provided to copy headers from a MessageHeaders collection to an array of MessageHeaderInfo objects.

Für den Zugriff auf die XML-Daten in einem Header können Sie GetReaderAtHeader aufrufen und einen XML-Leser für den Headerindex zurückgeben.To access the XML data in a header, you can call GetReaderAtHeader and return an XML reader for the specific header index. Verwenden Sie zum Deserialisieren des Headerinhalts in ein Objekt GetHeader<T>(Int32) oder eine der anderen Überladungen.If you want to deserialize the header contents into an object, use GetHeader<T>(Int32) or one of the other overloads. Die grundlegendsten Überladungen deserialisieren Header mit dem DataContractSerializer, der standardmäßig konfiguriert wurde.The most basic overloads deserialize headers using the DataContractSerializer configured in the default way. Wenn Sie ein anderes Serialisierungsprogramm oder eine andere Konfiguration von DataContractSerializer verwenden möchten, nutzen Sie eine der Überladungen, die ein XmlObjectSerializer akzeptieren.If you want to use a different serializer or a different configuration of the DataContractSerializer, use one of the overloads that take an XmlObjectSerializer. Einige Überladungen akzeptieren auch den Headernamen, Namespace und optional eine Liste von Actor-Werte anstelle eines Index; dies ist eine Kombination von FindHeader und GetHeader.There are also overloads that take the header name, namespace, and optionally a list of Actor values instead of an index; this is a combination of FindHeader and GetHeader.

Arbeiten mit EigenschaftenWorking with Properties

Eine Message-Instanz kann eine beliebige Anzahl von benannten Objekten beliebiger Typen enthalten.A Message instance can contain an arbitrary number of named objects of arbitrary types. Auf diese Auflistung wird über die Properties-Eigenschaft vom Typ MessageProperties zugegriffen.This collection is accessed through the Properties property of type MessageProperties. Die Auflistung implementiert die IDictionary<TKey,TValue>-Schnittstelle und fungiert als Zuordnung von String zu Object.The collection implements the IDictionary<TKey,TValue> interface and acts as a mapping from String to Object. Normalerweise Eigenschaftswerte direkt an einen beliebigen Teil der Nachricht bei der Übertragung nicht zuordnen, allerdings bieten vielmehr verschiedene Nachricht Verarbeitung Hinweise für die Kanäle im WCF-Kanalstapel oder auf die CopyTo(MessageHeaderInfo[], Int32) dienstframework.Normally, property values do not map directly to any part of the message on the wire, but rather provide various message processing hints to the various channels in the WCF channel stack or to the CopyTo(MessageHeaderInfo[], Int32) service framework. Ein Beispiel finden Sie unter Daten übertragen Architekturübersicht.For an example, see Data Transfer Architectural Overview.

Erben von der MeldungsklasseInheriting from the Message Class

Erstellen Sie eine von der CreateMessage-Klasse abgeleitete Klasse, wenn die mit Message erstellten integrierten Nachrichtentypen nicht den Anforderungen entsprechen.If the built-in message types created using CreateMessage do not meet your requirements, create a class that derives from the Message class.

Definieren des NachrichtentextinhaltsDefining the Message Body Contents

Für den Zugriff auf Daten innerhalb eines Nachrichtentexts gibt es drei grundlegende Verfahren: Schreiben, Lesen und Kopieren in einen Puffer.Three primary techniques exist for accessing data within a message body: writing, reading, and copying it to a buffer. Diese Verfahren führen im Endeffekt dazu, dass die OnWriteBodyContents-Methode, die OnGetReaderAtBodyContents-Methode bzw. die OnCreateBufferedCopy-Methode in der abgeleiteten Message-Klasse aufgerufen wird.These operations ultimately result in the OnWriteBodyContents, OnGetReaderAtBodyContents, and OnCreateBufferedCopy methods being called, respectively, on your derived class of Message. Die Message-Basisklasse stellt sicher, dass für jede Message-Instanz nur eine dieser Methoden aufgerufen wird und dieser Vorgang jeweils nur einmal stattfindet.The base Message class guarantees that only one of these methods is called for each Message instance, and that it is not called more than once. Die Basisklasse stellt auch sicher, dass die Methoden nicht für eine geschlossene Nachricht aufgerufen werden.The base class also ensures that the methods are not called on a closed message. Es ist nicht erforderlich, den Nachrichtenzustand in der Implementierung zu verfolgen.There is no need to track the message state in your implementation.

OnWriteBodyContents ist eine abstrakte Methode und muss implementiert werden.OnWriteBodyContents is an abstract method and must be implemented. Die grundlegendste Weise zum Definieren des Textinhalts der Nachricht ist, mit dieser Methode zu schreiben.The most basic way to define the body contents of your message is to write using this method. Zum Beispiel enthält die folgende Nachricht 100.000 Zufallszahlen von 1 bis 20.For example, the following message contains 100,000 random numbers from 1 to 20.

public class RandomMessage : Message
{
    override protected  void  OnWriteBodyContents(XmlDictionaryWriter writer)
    {
        Random r = new Random();
        for (int i = 0; i <100000; i++)
        {
            writer.WriteStartElement("number");
            writer.WriteValue(r.Next(1,20));
            writer.WriteEndElement();
        }
    }    
    //code omitted�
Public Class RandomMessage
    Inherits Message

    Protected Overrides Sub OnWriteBodyContents( _
            ByVal writer As XmlDictionaryWriter)
        Dim r As New Random()
        Dim i As Integer
        For i = 0 To 99999
            writer.WriteStartElement("number")
            writer.WriteValue(r.Next(1, 20))
            writer.WriteEndElement()
        Next i

    End Sub
    ' Code omitted.

Die OnGetReaderAtBodyContents-Methode und die OnCreateBufferedCopy-Methode verfügen über Standardimplementierungen, die in den meisten Fällen funktionieren.The OnGetReaderAtBodyContents and OnCreateBufferedCopy methods have default implementations that work for most cases. Die Standardimplementierungen rufen OnWriteBodyContents auf, speichern die Ergebnisse im Puffer und arbeiten mit dem resultierenden Puffer.The default implementations call OnWriteBodyContents, buffer the results, and work with the resulting buffer. In einigen Fällen genügt dies möglicherweise nicht.However, in some cases this may not be enough. In vorhergehenden Beispiel führt das Lesen der Nachricht dazu, dass 100.000 XML-Elemente im Puffer gespeichert werden, was unter Umständen nicht wünschenswert ist.In the preceding example, reading the message results in 100,000 XML elements being buffered, which might not be desirable. Es kann empfehlenswert sein, OnGetReaderAtBodyContents zu überschreiben, um eine benutzerdefinierte abgeleitete XmlDictionaryReaderKlasse zurückzugeben, die Zufallszahlen bereitstellt.You might want to override OnGetReaderAtBodyContents to return a custom XmlDictionaryReader derived class that serves up random numbers. Sie können dann OnWriteBodyContents überschreiben, um den von der OnGetReaderAtBodyContents-Eigenschaft zurückgegebenen Leser zu verwenden, wie im folgenden Beispiel dargestellt.You can then override OnWriteBodyContents to use the reader that the OnGetReaderAtBodyContents property returns, as shown in the following example.

    public override MessageHeaders Headers
    {
        get { throw new Exception("The method or operation is not implemented."); }
    }

    public override MessageProperties Properties
    {
        get { throw new Exception("The method or operation is not implemented."); }
    }

    public override MessageVersion Version
    {
        get { throw new Exception("The method or operation is not implemented."); }
    }
}

public class RandomMessage2 : Message
{
    override protected XmlDictionaryReader OnGetReaderAtBodyContents()
    {
    return new RandomNumbersXmlReader();
    }
    
    override protected void OnWriteBodyContents(XmlDictionaryWriter writer)
    {
        XmlDictionaryReader xdr = OnGetReaderAtBodyContents();
        writer.WriteNode(xdr, true); 
    }    
    public override MessageHeaders Headers
    {
        get { throw new Exception("The method or operation is not implemented."); }
    }
    
    public override MessageProperties Properties
    {
        get { throw new Exception("The method or operation is not implemented."); }
    }
    
    public override MessageVersion Version
    {
        get { throw new Exception("The method or operation is not implemented."); }
    }
}

public class RandomNumbersXmlReader : XmlDictionaryReader
{
    //code to serve up 100000 random numbers in XML form omitted�

    Public Overrides ReadOnly Property Headers() As MessageHeaders
        Get
            Throw New Exception("The method or operation is not implemented.")
        End Get
    End Property

    Public Overrides ReadOnly Property Properties() As MessageProperties
        Get
            Throw New Exception("The method or operation is not implemented.")
        End Get
    End Property

    Public Overrides ReadOnly Property Version() As MessageVersion
        Get
            Throw New Exception("The method or operation is not implemented.")
        End Get
    End Property
End Class

Public Class RandomMessage2
    Inherits Message
    
    Protected Overrides Function OnGetReaderAtBodyContents() As XmlDictionaryReader 
        Return New RandomNumbersXmlReader()
    
    End Function
    
    
    Protected Overrides Sub OnWriteBodyContents(ByVal writer As XmlDictionaryWriter) 
        Dim xdr As XmlDictionaryReader = OnGetReaderAtBodyContents()
        writer.WriteNode(xdr, True)
    
    End Sub
    
    Public Overrides ReadOnly Property Headers() As MessageHeaders 
        Get
            Throw New Exception("The method or operation is not implemented.")
        End Get
    End Property 
    
    Public Overrides ReadOnly Property Properties() As MessageProperties 
        Get
            Throw New Exception("The method or operation is not implemented.")
        End Get
    End Property 
    
    Public Overrides ReadOnly Property Version() As MessageVersion 
        Get
            Throw New Exception("The method or operation is not implemented.")
        End Get
    End Property
End Class

Public Class RandomNumbersXmlReader
    Inherits XmlDictionaryReader
    'code to serve up 100000 random numbers in XML form omitted

Auf ähnliche Weise können Sie OnCreateBufferedCopy überschreiben, um eine eigene abgeleitete MessageBuffer-Klasse zurückzugeben.Similarly, you might want to override OnCreateBufferedCopy to return your own MessageBuffer derived class.

Zusätzlich zum Bereitstellen von Nachrichtentextinhalt muss die abgeleitete Nachrichtenklasse auch die Version-Eigenschaft, die Headers-Eigenschaft und die Properties-Eigenschaft überschreiben.In addition to providing message body contents, your message derived class must also override the Version, Headers, and Properties properties.

Beachten Sie, dass beim Erstellen der Kopie einer Nachricht die Kopie die Nachrichtenheader aus dem Original verwendet.Note that if you create a copy of a message, the copy uses the message headers from the original.

Andere Member, die überschrieben werden könnenOther Members that Can Be Overridden

Sie können die OnWriteStartEnvelope-Methode, die OnWriteStartHeaders-Methode und die OnWriteStartBody-Methode überschreiben, um anzugeben, wie der SOAP-Umschlag, die SOAP-Header und die SOAP-Textelement-Starttags geschrieben werden. Diese entsprechen normalerweise <soap:Envelope>, <soap:Header>, und <soap:Body>.You can override the OnWriteStartEnvelope, OnWriteStartHeaders, and OnWriteStartBody methods to specify how the SOAP envelope, SOAP headers, and SOAP body element start tags are written out. These normally correspond to <soap:Envelope>, <soap:Header>, and <soap:Body>. Diese Methoden sollten normalerweise nichts schreiben, wenn die Version-Eigenschaft MessageVersion.None zurückgibt.These methods should normally not write anything out if the Version property returns MessageVersion.None.

Hinweis

Die Standardimplementierung von OnGetReaderAtBodyContents ruft OnWriteStartEnvelope und OnWriteStartBody auf, bevor OnWriteBodyContents aufgerufen wird und die Ergebnisse im Puffer gespeichert werden.The default implementation of OnGetReaderAtBodyContents calls OnWriteStartEnvelope and OnWriteStartBody before calling OnWriteBodyContents and buffering the results. Header werden nicht geschrieben.Headers are not written out.

Überschreiben Sie die OnWriteMessage-Methode, um das Verfahren zu ändern, wie die gesamte Nachricht aus den verschiedenen Teilen erstellt wird.Override the OnWriteMessage method to change the way the entire message is constructed from its various pieces. Die OnWriteMessage-Methode wird aus WriteMessage und aus der OnCreateBufferedCopy-Standardimplementierung aufgerufen.The OnWriteMessage method is called from WriteMessage and from the default OnCreateBufferedCopy implementation. Beachten Sie, dass das Überschreiben von WriteMessage keine empfohlene Vorgehensweise ist.Note that overriding WriteMessage is not a best practice. Es ist besser, die entsprechenden On-Methoden zu überschreiben, z. B OnWriteStartEnvelope, OnWriteStartHeaders und OnWriteBodyContents.It is better to override the appropriate On methods (for example, OnWriteStartEnvelope, OnWriteStartHeaders, and OnWriteBodyContents.

Überschreiben Sie OnBodyToString, um zu überschreiben, wie der Nachrichtentext während des Debuggens dargestellt wird.Override OnBodyToString to override how your message body is represented during debugging. Der Standard ist die Darstellung als drei Punkte ("…").The default is to represent it as three dots ("…"). Diese Methode kann mehrfach ausgerufen werden, wenn der Nachrichtenzustand nicht "Geschlossen" lautet.Note that this method can be called multiple times when the message state is anything other than Closed. Eine Implementierung dieser Methode sollte nie eine Aktion verursachen, die nur einmal ausgeführt werden muss (wie das Lesen eines Vorwärtsstreams).An implementation of this method should never cause any action that must be performed only once (such as reading from a forward-only stream).

Überschreiben Sie die OnGetBodyAttribute-Methode, um den Zugriff auf Attribute im SOAP-Textelement zuzulassen.Override the OnGetBodyAttribute method to allow access to attributes on the SOAP body element. Diese Methode kann beliebig oft aufgerufen werden, der Message-Basistyp stellt jedoch sicher, dass sie nur dann aufgerufen wird, wenn der Zustand der Nachricht "Erstellt" lautet.This method can be called any number of times, but the Message base type guarantees that it is only called when the message is in the Created state. Es ist nicht erforderlich, den Zustand in einer Implementierung zu überprüfen.It is not required to check the state in an implementation. Die Standardimplementierung gibt immer null zurück, was bedeutet, dass im Textelement keine Attribute vorhanden sind.The default implementation always returns null, which indicates that there are no attributes on the body element.

Soll das Message-Objekt eine spezielle Bereinigung ausführen, wenn der Nachrichtentext nicht mehr benötigt wird, können Sie OnClose überschreiben.If your Message object must do any special cleanup when the message body is no longer required, you can override OnClose. Bei der Standardimplementierung wird keine Aktion ausgeführt.The default implementation does nothing.

Die IsEmpty-Eigenschaft und die IsFault-Eigenschaft können überschrieben werden.The IsEmpty and IsFault properties can be overridden. Standardmäßig geben beide false zurück.By default, both return false.