Benutzerdefinierte EncoderCustom Encoders

In diesem Thema wird das Erstellen benutzerdefinierter Encoder behandelt.This topic discusses how to create custom encoders.

In Windows Communication Foundation (WCF)Windows Communication Foundation (WCF), Sie verwenden eine Bindung angeben, wie Daten in einem Netzwerk zwischen Endpunkten übertragen.In Windows Communication Foundation (WCF)Windows Communication Foundation (WCF), you use a binding to specify how to transfer data across a network between endpoints. Eine Bindung besteht aus einer Folge von Bindungselementen.A binding is made up of a sequence of binding elements. Eine Bindung enthält optionale protokollbindungselemente, wie z. B. Sicherheit, ein erforderliches Nachrichtenencoder Bindungselement und ein erforderliches Transportbindungselement.A binding includes optional protocol binding elements such as security, a required Message Encoder binding element, and a required transport binding element. Ein Nachrichtenencoder wird von einem Nachrichtencodierungs-Bindungselement dargestellt.A message encoder is represented by a message encoding binding element. WCFWCF verfügt über drei Nachrichtenencoder: einen Binärencoder, einen Transmission Optimization Mechanism (MTOM)-Encoder und einen Textencoder.Three message encoders are included in WCFWCF: Binary, Message Transmission Optimization Mechanism (MTOM), and Text.

Ein Bindungselement für die Nachrichtencodierung dient zum Serialisieren einer ausgehenden Message. Anschließend wird die Nachricht an den Transport übergeben, oder die serialisierte Form einer Nachricht wird vom Transport empfangen und an die Protokollebene übergeben. Ist die Protokollebene nicht vorhanden, erfolgt die Übergabe an die Anwendung.A message encoding binding element serializes an outgoing Message and passes it to the transport, or receives the serialized form of a message from the transport and passes it to the protocol layer if present, or to the application, if not present.

Message-Instanzen werden von Nachrichtenencodern in und aus Übertragungsdarstellungen umgewandelt.Message encoders transform Message instances to and from a wire representation. Obgleich Encoder als Elemente beschrieben werden, die der Transportebene des Kanalstapels übergeordnet sind, befinden sie sich eigentlich auf der Transportebene.Although encoders are described as sitting above the transport layer in the channel stack, they reside inside the transport layer. Von Transporten (beispielsweise HTTP) wird die Nachricht gemäß den Anforderungen des Transportstandards formatiert.Transports (for example HTTP) format the message according to the requirements of the transport standard. Die Encoder (beispielsweise Text-XML) dienen lediglich zum Codieren der Nachricht.Encoders (for example Text Xml) just encode the message.

Beim Herstellen einer Verbindung mit einem vorhandenen Client oder Server muss möglicherweise eine bestimmte Nachrichtencodierung verwendet werden.When connecting to a preexisting client or server, you may not have a choice about using a particular message encoding. Sie können jedoch WCFWCF-Dienste über mehrere Endpunkte bereitstellen, von denen jeweils eine andere Nachrichtencodierung verwendet wird.However, WCFWCF services can be made accessible through multiple endpoints, each with a different message encoder. Wenn ein einzelner Encoder nicht für alle Zielbenutzer des Diensts ausreicht, können Sie den Dienst über mehrere Endpunkte hinweg verfügbar machen.When a single encoder does not cover the entire audience for your service, consider exposing your service over multiple endpoints. Somit kann von Clientanwendungen der optimale Endpunkt gewählt werden.Client applications can then choose the endpoint that is best for them. Die Verwendung mehrerer Endpunkte ermöglicht es Ihnen, die Vorteile anderer Nachrichtencodierungen mit anderen Bindungselementen zu kombinieren.Using multiple endpoints allows you to combine the advantages of different message encoders with other binding elements.

Vom System bereitgestellte EncoderSystem-Provided Encoders

Von WCFWCF werden mehrere systemeigene Bindungen bereitgestellt, um die häufigsten Anwendungsszenarios abzudecken.WCFWCF provides several system-provided bindings that are designed to cover the most common application scenarios. In jeder dieser Bindungen wird ein Transport mit einem Nachrichtenencoder und anderen Optionen (beispielsweise Sicherheit) kombiniert.Each of these bindings combine a transport, message encoder, and other options (security, for example). In diesem Thema wird das Erweitern der in Text integrierten Nachrichtenencoder vom Typ Binary, MTOM und WCFWCF erläutert. Darüber hinaus erhalten Sie Informationen zum Erstellen benutzerdefinierter Encoder.This topic describes how to extend the Text, Binary, and MTOM message encoders that are included in WCFWCF, or create your own custom encoder. Der Textnachrichtenencoder unterstützt sowohl reine XML-Codierung als auch SOAP-Codierungen.The text message encoder supports both a plain XML encoding as well as SOAP encodings. Der reine XML-Codierungsmodus des Textnachrichtenencoders wird als POX-Encoder ("Plain Old XML") bezeichnet, um ihn von der textbasierten SOAP-Codierung zu unterscheiden.The plain XML encoding mode of the text message encoder is called the POX ("Plain Old XML") encoder to distinguish it from the text-based SOAP encoding.

Weitere Informationen finden Sie unterFor more information aboutdie Kombinationen von gebotenen vom System bereitgestellten Bindungen, Bindungselemente finden Sie im entsprechenden Abschnitt in Wählen eines Transports. the combinations of binding elements provided by the system-provided bindings, see the corresponding section in Choosing a Transport.

Arbeiten mit vom System bereitgestellten EncodernHow to Work with System-Provided Encoders

Das Hinzufügen einer Codierung zu einem Bindungselement erfolgt mithilfe einer von MessageEncodingBindingElement abgeleiteten Klasse.An encoding is added to a binding using a class derived from MessageEncodingBindingElement.

Von WCFWCF werden die folgenden von der MessageEncodingBindingElement-Klasse abgeleiteten Bindungselementtypen bereitgestellt, mit denen sich Text-, Binär- sowie MTOM-Codierungen verwenden lassen:WCFWCF provides the following types of binding elements derived from the MessageEncodingBindingElement class that can provide for text, binary and Message Transmission Optimization Mechanism (MTOM) encoding:

  • TextMessageEncodingBindingElement: Der am wenigsten effiziente Encoder für XML-Nachrichten, der jedoch das höchste Maß an Interoperabilität bietet.TextMessageEncodingBindingElement: The most interoperable, but the least efficient encoder for XML messages. Text-XML kann in der Regel von Webdiensten oder Webdienstclients interpretiert werden.A Web service or Web service client can generally understand textual XML. Das Übermitteln umfangreicher Blöcke binärer Daten in Textform ist jedoch wenig effizient.However, transmitting large blocks of binary data as text is not efficient.

  • Die BinaryMessageEncodingBindingElement-Klasse stellt das Bindungselement dar, von dem die Zeichencodierung und die für binäre XML-Nachrichten verwendete Nachrichtenversion angegeben werden.BinaryMessageEncodingBindingElement: Represents the binding element that specifies the character encoding and message versioning used for binary-based XML messages. Hierbei handelt es sich um die effizienteste Codierungsoption, diese besitzt jedoch gleichzeitig die geringste Interoperabilität, da sie lediglich von WCFWCF-Endpunkten unterstützt wird.This is most efficient of the encoding options, but the least interoperable, because it is only supported by WCFWCF endpoints.

  • <System.ServiceModel.Channels.MTOMMessageEncodingBindingElement>: stellt das Bindungselement, der angibt, das die zeichencodierung und Nachrichtenversion für eine Meldung mit MTOM Message Transmission Optimization Mechanism (MTOM).< System.ServiceModel.Channels.MTOMMessageEncodingBindingElement>: Represents the binding element that specifies the character encoding and message versioning used for a message using a Message Transmission Optimization Mechanism (MTOM) encoding. MTOM ist eine effiziente Technologie zum Senden von Binärdaten in WCFWCF-Meldungen.MTOM is an efficient technology for transmitting binary data in WCFWCF messages. Der MTOM-Encoder versucht, einen Ausgleich zwischen Effizienz und Interoperabilität zu erschaffen.The MTOM encoder attempts to balance between efficiency and interoperability. Die MTOM-Verschlüsselung überträgt die meisten XML-Daten in Textform, optimiert aber große Binärdatenblöcke durch Übertragung ohne Textkonvertierung.The MTOM encoding transmits most XML in textual form, but optimizes large blocks of binary data by transmitting them as-is, without conversion to text.

Vom Bindungselement wird eine Binär-, MTOM- oder Text-MessageEncoderFactory erstellt.The binding element creates a binary, MTOM, or text MessageEncoderFactory. Von der Factory wird eine MessageEncoderFactory-Binär-, MTOM- oder Textinstanz erstellt.The factory creates a binary, MTOM, or text MessageEncoderFactory instance. Üblicherweise ist lediglich eine einzelne Instanz vorhanden.Typically, there is only a single instance. Bei Verwendung von Sitzungen kann jedoch für jede Sitzung ein anderer Encoder bereitgestellt werden.However if sessions are used, a different encoder may be provided to each session. Vom Binärencoder wird diese Möglichkeit zum Koordinieren dynamischer Wörterbücher genutzt (siehe XML-Infrastruktur).The Binary encoder makes use of this to coordinate dynamic dictionaries (see XML Infrastructure).

Die Methoden ReadMessage und WriteMessage bilden den Kern der Encoder.The ReadMessage and WriteMessage methods are the core of the encoders. Sie dienen zum Lesen einer Nachricht aus einem Stream oder aus einem Byte-Array.The methods provide for reading a message from a stream or from a Byte array. Bytearrays werden verwendet, wenn der Transport im Puffermodus betrieben wird.Byte arrays are used when the transport is operating in buffered mode. Nachrichten werden stets in Streams geschrieben.Messages are always written to streams. Muss die Nachricht gepuffert werden, wird hierzu ein Stream bereitgestellt.If the transport must buffer the message, it provides a stream that does the buffering.

Die restlichen Member arbeiten mit Supportinhalten, Medientypen und MessageVersion.The rest of the members work with support content, media types, and MessageVersion. Die Encodermethoden werden vom Transport aufgerufen, um zu testen, ob die eingehende Nachricht damit decodiert werden kann, oder um festzustellen, ob die ausgehende Nachricht für diesen Encoder geeignet ist.The transport calls these encoder methods to test whether the incoming message can be decoded by it, or to determine if the outgoing message is valid for this encoder.

Mit jeder der drei Encoderimplementierungen werden Eigenschaften hinzugefügt, die für die jeweilige Codierung benötigt werden. Darüber hinaus sind sie vollständig konfigurierbar.Each of the three encoder implementations adds properties that are relevant to the specific encodings and is fully configurable. Von den Encodern werden überdies Readerkontingente mit sicheren Standardeinstellungen verfügbar gemacht.The encoders also expose reader quotas that have secure defaults. Informationen zu Kontingenten finden Sie im Thema zur XML-Infrastruktur.See XML Infrastructure for a discussion of the quotas.

Funktionen der vom System bereitgestellten EncoderFeatures of System-Provided Encoders

Die vom System bereitgestellten Encoder verfügen über eine Reihe von Funktionen.There are a number of features provided by the system-provided encoders.

PoolingPooling

Für jede der Encoderimplementierungen wird versucht, ein Höchstmaß an Pooling zu erzielen.Each of the encoder implementations tries to pool as much as possible. Eine geeignete Vorgehensweise zum Verbessern der Leistung verwalteten Codes besteht im Verringern der Speicherbelegung.Reducing allocations is a key way to improve the performance of managed code. Für das Pooling wird von den Implementierungen die SynchronizedPool-Klasse verwendet.To accomplish this pooling, the implementations use the SynchronizedPool class. Die C#-Datei enthält eine Beschreibung der zusätzlichen, von dieser Klasse verwendeten Optimierungen.The C# file contains a description of the additional optimizations used by this class.

Die Instanzen XmlDictionaryReader und XmlDictionaryWriter werden in einem Pool zusammengefasst und neu initialisiert, um eine Neuzuordnung von Instanzen für jede Nachricht zu unterbinden.XmlDictionaryReader and XmlDictionaryWriter instances are pooled and reinitialized to prevent allocating new ones for each message. Bei einem Reader wird dieser mithilfe eines OnClose-Rückrufs zurückgefordert, wenn Close() aufgerufen wird.For the readers, an OnClose callback reclaims the reader when Close() is called. Vom Encoder werden auch einige Nachrichtenzustandsobjekte wiederverwendet, die bei der Nachrichtenerstellung verwendet wurden.The encoder also recycles some message state objects used when constructing messages. Die Größe dieser Pools kann über die Eigenschaften MaxReadPoolSize und MaxWritePoolSize für jede der drei von MessageEncodingBindingElement abgeleiteten Klassen konfiguriert werden.The sizes of these pools are configurable by the MaxReadPoolSize and MaxWritePoolSize properties on each of the three classes derived from MessageEncodingBindingElement.

BinärcodierungBinary Encoding

Werden bei der Binärcodierung Sitzungen verwendet, muss die dynamische Wörterbuchzeichenfolge an den Empfänger der Nachricht übermittelt werden.When binary encoding uses sessions, the dynamic dictionary string must be communicated to the receiver of the message. Hierzu werden der Nachricht die dynamischen Wörterbuchzeichenfolgen als Präfix hinzugefügt.This is done by prefixing the message with the dynamic dictionary strings. Vom Empfänger werden die Zeichenfolgen entfernt und der Sitzung hinzugefügt. Anschließend wird die Nachricht verarbeitet.The receiver strips off the strings, adds them to the session, and processes the message. Für die ordnungsgemäße Übergabe der Wörterbuchzeichenfolgen muss der Transport gepuffert werden.Correctly passing dictionary strings requires that the transport be buffered.

Die Zeichenfolgen werden der Meldung mithilfe einer internen AddSessionInformationToMessage-Methode angehängt.The strings are appended to the message by an internal AddSessionInformationToMessage method. Mit dieser Methode werden die Zeichenfolgen dem Nachrichtenanfang als UTF-8 hinzugefügt. Davor wird als Präfix die Länge der Zeichenfolgen eingefügt.It adds the strings as UTF-8 to the front of the message prefixed with their length. Der gesamte Wörterbuchheader wird daraufhin mit einem Präfix versehen, das die Datenlänge enthält.The entire dictionary header is then prefixed with the length of its data. Der umgekehrte Vorgang erfolgt mittels einer internen ExtractSessionInformationFromMessage-Methode.The reverse operation is performed by an internal ExtractSessionInformationFromMessage method.

Zusätzlich zum Verarbeiten dynamischer Wörterbuchschlüssel erfolgt der Empfang sitzungsbasierter Meldungen auf eindeutige Weise.In addition to processing dynamic dictionary keys, buffered sessionful messages are received in a unique way. Anstatt einen Reader über das Dokument zu erstellen und dieses anschließend zu verarbeiten, wird der binäre Stream bei der Binärcodierung mithilfe der internen MessagePatterns-Klasse zerlegt.Instead of creating a reader over the document and processing it, the binary encoder uses the internal MessagePatterns class to deconstruct the binary stream. Diesem Vorgang liegt folgender Gedanke zugrunde: Die meisten Nachrichten besitzen einen bestimmten Satz von Headern, die in einer bestimmten Reihenfolge angezeigt werden, wenn sie von WCFWCF generiert wurden.The idea is that most messages have a certain set of headers that show up in a certain order when generated by WCFWCF. Die Nachricht wird vom Mustersystem auf Basis der jeweiligen Erwartung zerlegt.The pattern system breaks the message apart based on what it expects. Ist der Vorgang erfolgreich, wird ohne XML-Analyse ein MessageHeaders-Objekt erstellt.If it is successful, it initializes a MessageHeaders object without parsing the XML. Andernfalls wird wieder die Standardmethode verwendet.If not, it falls back to the standard method.

MTOM-CodierungMTOM Encoding

Die < System.ServiceModel.Channels.MTOMMessageEncodingBindingElement>-Klasse verfügt über eine zusätzliche Konfigurationseigenschaft mit dem Namen < System.ServiceModel.Channels.MTOMMessageEncodingBindingElement. MaxBufferSize % 2A >.The < System.ServiceModel.Channels.MTOMMessageEncodingBindingElement> class has an additional configuration property called < System.ServiceModel.Channels.MTOMMessageEncodingBindingElement.MaxBufferSize%2A>. Hierdurch wird eine Obergrenze für die Menge der Daten festgelegt, die beim Lesen einer Nachricht gepuffert werden dürfen.This places an upper bound on how much data it is allowed to buffer during the process of reading a message. Das XML Information Set (Infoset) sowie andere MIME-Teile müssen möglicherweise gepuffert werden, um MIME-Teile wieder zu einer einzelnen Nachricht zusammenzufügen.The XML Information Set (Infoset), or other MIME parts, may need to be buffered to reassemble all the MIME parts into a single message.

Für das ordnungsgemäße Funktionieren mit HTTP werden vom internen MTOM-Nachrichtenencoder einige interne APIs für GetContentType (ebenfalls intern) und WriteMessage bereitgestellt. Letzteres Element ist öffentlich und kann außer Kraft gesetzt werden.To work correctly with HTTP, the internal MTOM message encoder class provides some internal APIs for GetContentType (which is also internal) and WriteMessage, which is public and can be overridden. Damit sichergestellt ist, dass die Werte in den HTTP-Headern mit den Werten in den MIME-Headern übereinstimmen, ist ein höheres Kommunikationsaufkommen erforderlich.More communication must occur to ensure values in the HTTP headers agree with values in the MIME headers.

Intern werden vom MTOM-Nachrichtenencoder Textreader von WCFWCF verwendet, und er ist vergleichbar mit dem Textencoder.Internally, the MTOM message encoder uses WCFWCF's text readers, and is similar to the Text encoder. Der Hauptunterschied besteht darin, dass vom MTOM-Nachrichtenencoder große Binärcodeabschnitte (oder "Binary Large Objects", so genannte BLOBs) optimiert werden, indem sie vor dem Einbetten in die Nachrichtenbytes nicht in eine Base-64-Codierung umgewandelt werden.The main difference is that it optimizes large chunks of binary, or "Binary Large Objects" (BLOBs), by not converting them to Base-64 encoding prior to being embedded into the message bytes. Stattdessen bleiben diese BLOBs extrahiert und werden als MIME-Anhänge referenziert.Instead, these BLOBs are kept extracted, and referenced as the MIME attachments.

Schreiben eigener EncoderWriting your own Encoder

Zum Implementieren eines eigenen Nachrichtenencoders müssen benutzerdefinierte Implementierungen der folgenden abstrakten Basisklassen bereitgestellt werden:To implement your own custom message encoder, you must provide custom implementations of the following abstract base classes:

Die Umwandlung der speicherinternen Version einer Nachricht zu einer Version, die in einen Stream geschrieben werden kann, ist Teil der MessageEncoder-Klasse, die als Factory für XML-Reader und XML-Writer mit Unterstützung für bestimmte XML-Codierungstypen fungiert.Converting from the in-memory representation of a message to a representation that can be written to a stream is encapsulated within the MessageEncoder class, which serves as a factory for XML readers and XML writers that support specific types of XML encodings.

Die Umwandlung zwischen dem standardmäßigen Transportprotokoll und der benutzerdefinierten Codierung wird anhand des in diese Methoden geschriebenen Codes behandelt.It is the code you write in these methods that handles conversion between the standard transport protocol, and your customized encoding.

Der nächste Schritt besteht im Codieren einer Factoryklasse zum Erstellen des benutzerdefinierten Encoders.Next you need to code a factory class that creates your custom encoder. Überschreiben Sie den Encoder, um eine Instanz des benutzerdefinierten MessageEncoder zurückzugeben.Override the Encoder to return an instance of your custom MessageEncoder.

Verbinden Sie anschließend die benutzerdefinierte MessageEncoderFactory mit dem Bindungselementstapel für die Konfiguration des Diensts oder des Clients durch Überschreiben der CreateMessageEncoderFactory-Methode, um eine Instanz der Factory zurückzugeben.Then connect your custom MessageEncoderFactory to the binding element stack used to configure the service or client by overriding the CreateMessageEncoderFactory method to return an instance of this factory.

Es gibt zwei Beispiele in WCFWCF , die diesen Prozess mit Beispielcode veranschaulichen: benutzerdefinierter Nachrichtenencoder: benutzerdefinierter Textencoder und benutzerdefinierter Nachrichtenencoder: Komprimierungsencoder.There are two samples provided with WCFWCF that illustrate this process with sample code: Custom Message Encoder: Custom Text Encoder and Custom Message Encoder: Compression Encoder.

Siehe auchSee Also

MessageEncodingBindingElement
MessageEncoderFactory
MessageEncoder
Datenübertragungsarchitektur: ÜbersichtData Transfer Architectural Overview
Auswählen eines NachrichtenencodersChoosing a Message Encoder
Auswählen eines TransportsChoosing a Transport