Benutzerdefinierter Nachrichtenencoder: Benutzerdefinierter TextencoderCustom Message Encoder: Custom Text Encoder

In diesem Beispiel wird veranschaulicht, wie einen benutzerdefinierter textnachrichtenencoder mit Windows Communication Foundation (WCF) implementiert.This sample demonstrates how to implement a custom text message encoder using Windows Communication Foundation (WCF).

Warnung

Die Beispiele sind möglicherweise bereits auf dem Computer installiert.The samples may already be installed on your machine. Suchen Sie nach dem folgenden Verzeichnis (Standardverzeichnis), bevor Sie fortfahren.Check for the following (default) directory before continuing.

<InstallDrive>:\WF_WCF_Samples

Wenn dieses Verzeichnis nicht vorhanden ist, fahren Sie mit Windows Communication Foundation (WCF) und Windows Workflow Foundation (WF) Samples for .NET Framework 4 aller Windows Communication Foundation (WCF) herunterladen und WFWF Beispiele.If this directory does not exist, go to Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4 to download all Windows Communication Foundation (WCF) and WFWF samples. Dieses Beispiel befindet sich im folgenden Verzeichnis.This sample is located in the following directory.

<InstallDrive>:\WF_WCF_Samples\WCF\Extensibility\MessageEncoder\Text

Die TextMessageEncodingBindingElement von WCF unterstützt nur die UTF-8, UTF-16 und Big Endean Unicode-Codierungen.The TextMessageEncodingBindingElement of WCF supports only the UTF-8, UTF-16 and Big Endean Unicode encodings. Der benutzerdefinierte Textnachrichtenencoder in diesem Beispiel unterstützt alle plattformunterstützten Zeichencodierungen, die zur Interoperabilität erforderlich sind.The custom text message encoder in this sample supports all platform-supported character encoding that may be required for interoperability. Das Beispiel besteht aus einem Clientkonsolenprogramm (.exe), einer von Internetinformationsdiensten (IIS) gehosteten Dienstbibliothek (.dll) und einer Bibliothek für Textnachrichtenencoder (.dll).The sample consists of a client console program (.exe), a service library (.dll) hosted by Internet Information Services (IIS) and a text message encoder library (.dll). Der Dienst implementiert einen Vertrag, der ein Anforderungs-Antwort-Kommunikationsmuster definiert.The service implements a contract that defines a request-reply communication pattern. Der Vertrag wird von der ICalculator-Schnittstelle definiert, die mathematische Operationen (Addieren, Subtrahieren, Multiplizieren und Dividieren) verfügbar macht.The contract is defined by the ICalculator interface, which exposes math operations (Add, Subtract, Multiply, and Divide). Der Client stellt synchrone Anforderungen an eine gegebene mathematische Operation, und der Dienst antwortet mit dem Ergebnis.The client makes synchronous requests to a given math operation and the service replies with the result. Sowohl Client als auch Dienst verwenden den CustomTextMessageEncoder anstelle des Standard-TextMessageEncodingBindingElement.Both client and service uses the CustomTextMessageEncoder instead of the default TextMessageEncodingBindingElement.

Die Implementierung für den benutzerdefinierten Encoder besteht aus einer Nachrichtenencoder-Factory, einem Nachrichtenencoder, einem Nachrichtencodierungs-Bindungselement und einem Konfigurationshandler. Es wird Folgendes veranschaulicht:The custom encoder implementation consists of a message encoder factory, a message encoder, a message encoding binding element and a configuration handler, and demonstrates the following:

  • Das Erstellen eines benutzerdefinierten Encoders und einer Encoder-Factory.Building a custom encoder and encoder factory.

  • Das Erstellen eines Bindungselements für einen benutzerdefinierten Encoder.Creating a binding element for a custom encoder.

  • Das Verwenden der benutzerdefinierten Bindungskonfiguration zum Integrieren von benutzerdefinierten Bindungselementen.Using the custom binding configuration for integrating custom binding elements.

  • Das Entwickeln eines benutzerdefinierten Konfigurationshandlers, um die Dateikonfiguration eines benutzerdefinierten Bindungselements zu ermöglichen.Developing a custom configuration handler to allow file configuration of a custom binding element.

So können Sie das Beispiel einrichten, erstellen und ausführenTo set up, build, and run the sample

  1. Installieren Sie ASP.NETASP.NET 4.0 mithilfe des folgenden Befehls.Install ASP.NETASP.NET 4.0 using the following command.

    %windir%\Microsoft.NET\Framework\v4.0.XXXXX\aspnet_regiis.exe /i /enable  
    
  2. Stellen Sie sicher, dass Sie ausgeführt haben die Setupprozedur für die Windows Communication Foundation-Beispiele zum einmaligen.Ensure that you have performed the One-Time Setup Procedure for the Windows Communication Foundation Samples.

  3. Führen Sie zum Erstellen der Projektmappe die Anweisungen im Erstellen der Windows Communication Foundation-Beispiele.To build the solution, follow the instructions in Building the Windows Communication Foundation Samples.

  4. Um das Beispiel in einer einzelnen oder computerübergreifenden Konfiguration ausführen möchten, folgen Sie den Anweisungen Ausführen der Windows Communication Foundation-Beispiele.To run the sample in a single- or cross-machine configuration, follow the instructions in Running the Windows Communication Foundation Samples.

Nachrichtenencoder-Factory und der NachrichtenencoderMessage Encoder Factory and the Message Encoder

Wenn der ServiceHost oder der Clientkanal geöffnet wird, erstellt die Entwurfszeit-Komponente CustomTextMessageBindingElement die CustomTextMessageEncoderFactory.When the ServiceHost or the client channel is opened, the design time component CustomTextMessageBindingElement creates the CustomTextMessageEncoderFactory. Die Factory erstellt den CustomTextMessageEncoder.The factory creates the CustomTextMessageEncoder. Der Nachrichtenencoder operiert sowohl im Streamingmodus als auch im Puffermodus.The message encoder operates both in the streaming mode and the buffered mode. Er verwendet den XmlReader und XmlWriter zum Schreiben bzw. Lesen der Nachrichten.It uses the XmlReader and XmlWriter to read and write the messages respectively. Im Gegensatz zu den optimierten XML-Readern und-Writern von WCF, die nur UTF-8, UTF-16 und Big-Endean Unicode unterstützen unterstützen diese Reader und Writer alle plattformunterstützten Codierungen.As opposed to the optimized XML readers and writers of WCF that support only UTF-8, UTF-16 and Big-Endean Unicode these readers and writers support all platform supported encoding.

Das folgende Codebeispiel zeigt den benutzerdefinierten Textnachrichtenencoder (CustomTextMessageEncoder).The following code example shows the CustomTextMessageEncoder.

public class CustomTextMessageEncoder : MessageEncoder  
{  
    private CustomTextMessageEncoderFactory factory;  
    private XmlWriterSettings writerSettings;  
    private string contentType;  

    public CustomTextMessageEncoder(CustomTextMessageEncoderFactory factory)  
    {  
        this.factory = factory;  

        this.writerSettings = new XmlWriterSettings();  
        this.writerSettings.Encoding = Encoding.GetEncoding(factory.CharSet);  
        this.contentType = string.Format("{0}; charset={1}",   
            this.factory.MediaType, this.writerSettings.Encoding.HeaderName);  
    }  

    public override string ContentType  
    {  
        get  
        {  
            return this.contentType;  
        }  
    }  

    public override string MediaType  
    {  
        get   
        {  
            return factory.MediaType;  
        }  
    }  

    public override MessageVersion MessageVersion  
    {  
        get   
        {  
            return this.factory.MessageVersion;  
        }  
    }  

    public override Message ReadMessage(ArraySegment<byte> buffer, BufferManager bufferManager, string contentType)  
    {     
        byte[] msgContents = new byte[buffer.Count];  
        Array.Copy(buffer.Array, buffer.Offset, msgContents, 0, msgContents.Length);  
        bufferManager.ReturnBuffer(buffer.Array);  

        MemoryStream stream = new MemoryStream(msgContents);  
        return ReadMessage(stream, int.MaxValue);  
    }  

    public override Message ReadMessage(Stream stream, int maxSizeOfHeaders, string contentType)  
    {  
        XmlReader reader = XmlReader.Create(stream);  
        return Message.CreateMessage(reader, maxSizeOfHeaders, this.MessageVersion);  
    }  

    public override ArraySegment<byte> WriteMessage(Message message, int maxMessageSize, BufferManager bufferManager, int messageOffset)  
    {  
        MemoryStream stream = new MemoryStream();  
        XmlWriter writer = XmlWriter.Create(stream, this.writerSettings);  
        message.WriteMessage(writer);  
        writer.Close();  

        byte[] messageBytes = stream.GetBuffer();  
        int messageLength = (int)stream.Position;  
        stream.Close();  

        int totalLength = messageLength + messageOffset;  
        byte[] totalBytes = bufferManager.TakeBuffer(totalLength);  
        Array.Copy(messageBytes, 0, totalBytes, messageOffset, messageLength);  

        ArraySegment<byte> byteArray = new ArraySegment<byte>(totalBytes, messageOffset, messageLength);  
        return byteArray;  
    }  

    public override void WriteMessage(Message message, Stream stream)  
    {  
        XmlWriter writer = XmlWriter.Create(stream, this.writerSettings);  
        message.WriteMessage(writer);  
        writer.Close();  
    }  
}  

Im folgenden Codebeispiel wird gezeigt, wie die Nachrichtenencoder-Factory erstellt wird.The following code example shows how to build the message encoder factory.

public class CustomTextMessageEncoderFactory : MessageEncoderFactory  
{  
    private MessageEncoder encoder;  
    private MessageVersion version;  
    private string mediaType;  
    private string charSet;  

    internal CustomTextMessageEncoderFactory(string mediaType, string charSet,  
        MessageVersion version)  
    {  
        this.version = version;  
        this.mediaType = mediaType;  
        this.charSet = charSet;  
        this.encoder = new CustomTextMessageEncoder(this);  
    }  

    public override MessageEncoder Encoder  
    {  
        get   
        {   
            return this.encoder;  
        }  
    }  

    public override MessageVersion MessageVersion  
    {  
        get   
        {   
            return this.version;  
        }  
    }  

    internal string MediaType  
    {  
        get  
        {  
            return this.mediaType;  
        }  
    }  

    internal string CharSet  
    {  
        get  
        {  
            return this.charSet;  
        }  
    }  
}  

Nachrichtencodierungs-BindungselementMessage Encoding Binding Element

Die Bindungselemente ermöglichen die Konfiguration des WCF-Laufzeitstapels.The binding elements allow the configuration of the WCF run-time stack. Um den benutzerdefinierten Nachrichtenencoder in einer WCF-Anwendung verwenden, ein Binding-Element ist erforderlich, die Nachrichtenencoder-Factory mit den entsprechenden Einstellungen auf der entsprechenden Ebene im Stapel zur Laufzeit erstellt.To use the custom message encoder in a WCF application, a binding element is required that creates the message encoder factory with the appropriate settings at the appropriate level in the run-time stack.

CustomTextMessageBindingElement wird von der Basisklasse BindingElement abgeleitet und erbt von der MessageEncodingBindingElement-Klasse.The CustomTextMessageBindingElement derives from the BindingElement base class and inherits from the MessageEncodingBindingElement class. Dadurch wird anderen WCF-Komponenten auf diesem Bindungselement als ein nachrichtencodierungs-Bindungselement erkannt.This allows other WCF components to recognize this binding element as being a message encoding binding element. Die Implementierung von CreateMessageEncoderFactory gibt eine Instanz der entsprechenden Nachrichtenencoder-Factory mit entsprechenden Einstellungen zurück.The implementation of CreateMessageEncoderFactory returns an instance of the matching message encoder factory with appropriate settings.

CustomTextMessageBindingElement macht Einstellungen für MessageVersion, ContentType und Encoding durch Eigenschaften verfügbar.The CustomTextMessageBindingElement exposes settings for MessageVersion, ContentType, and Encoding through properties. Der Encoder unterstützt sowohl die Soap11Addressing- als auch die Soap12Addressing1-Version.The encoder supports both Soap11Addressing and Soap12Addressing1 versions. Als Standard ist Soap11Addressing1 eingestellt.The default is Soap11Addressing1. Der Standardwert von ContentType lautet "text/xml".The default value of the ContentType is "text/xml". Die Encoding-Eigenschaft ermöglicht es Ihnen, den Wert der gewünschten Zeichencodierung festzulegen.The Encoding property allows you to set the value of the desired character encoding. Der Beispielclient und-Dienst verwendet die ISO-8859-1 (latein1)-zeichencodierung, die von nicht unterstützt die TextMessageEncodingBindingElement von WCF.The sample client and service uses the ISO-8859-1 (Latin1) character encoding, which is not supported by the TextMessageEncodingBindingElement of WCF.

Im folgenden Code wird gezeigt, wie die Bindung programmgesteuert mithilfe des benutzerdefinierten Textnachrichtenencoders erstellt wird.The following code shows how to programmatically create the binding using the custom text message encoder.

ICollection<BindingElement> bindingElements = new List<BindingElement>();  
HttpTransportBindingElement httpBindingElement = new HttpTransportBindingElement();  
CustomTextMessageBindingElement textBindingElement = new CustomTextMessageBindingElement();  
bindingElements.Add(textBindingElement);  
bindingElements.Add(httpBindingElement);  
CustomBinding binding = new CustomBinding(bindingElements);  

Hinzufügen von Metadaten-Unterstützung zum Nachrichtencodierungs-BindungselementAdding Metadata Support to the Message Encoding Binding Element

Jeder Typ, der aus MessageEncodingBindingElement abgeleitet wird, ist für die Aktualisierung der Version der SOAP-Bindung im für den Dienst generierten WSDL-Dokument verantwortlich.Any type that derives from MessageEncodingBindingElement is responsible for updating the version of the SOAP binding in the WSDL document generated for the service. Dies erfolgt durch Implementierung der ExportEndpoint-Methode in der IWsdlExportExtension-Schnittstelle und anschließende Änderung des generierten WSDL.This is done by implementing the ExportEndpoint method on the IWsdlExportExtension interface and then modifying the generated WSDL. In diesem Beispiel verwendet CustomTextMessageBindingElement die WSDL-Exportlogik aus TextMessageEncodingBinidngElement.In this sample, the CustomTextMessageBindingElement uses the WSDL export logic from the TextMessageEncodingBinidngElement.

Für dieses Beispiel wird die Clientkonfiguration per Hand konfiguriert.For this sample, the client configuration is hand configured. Sie können Svcutil.exe nicht zur Generierung der Clientkonfiguration verwenden, da CustomTextMessageBindingElement keine Richtlinienassertion zur Beschreibung seines Verhaltens exportiert.You cannot use Svcutil.exe to generate the client configuration because the CustomTextMessageBindingElement does not export a policy assertion to describe its behavior. Sie sollten im Allgemeinen die IPolicyExportExtension-Schnittstelle auf einem benutzerdefinierten Bindungselement implementieren, um eine benutzerdefinierte Richtlinienassertion zu exportieren, die das Verhalten oder die Funktion beschreibt, die vom Bindungselement implementiert wurde.You should generally implement the IPolicyExportExtension interface on a custom binding element to export a custom policy assertion that describes the behavior or capability implemented by the binding element. Ein Beispiel für ein benutzerdefiniertes Bindungselement eine Richtlinienassertion zu exportieren, finden Sie unter der Transport: UDP Beispiel.For an example of how to export a policy assertion for a custom binding element, see the Transport: UDP sample.

Bindungskonfigurationshandler zur NachrichtencodierungMessage Encoding Binding Configuration Handler

Im vorherigen Abschnitt wird gezeigt, wie der benutzerdefinierte Textnachrichtenencoder programmgesteuert verwendet wird.The previous section shows how to use the custom text message encoder programmatically. CustomTextMessageEncodingBindingSection implementiert einen Konfigurationshandler, der es Ihnen ermöglicht, die Verwendung eines benutzerdefinierten Textnachrichtenencoders innerhalb einer Konfigurationsdatei festzulegen.The CustomTextMessageEncodingBindingSection implements a configuration handler that allows you to specify the use of a custom text message encoder within a configuration file. Die CustomTextMessageEncodingBindingSection-Klasse wird aus der BindingElementExtensionElement-Klasse abgeleitet.The CustomTextMessageEncodingBindingSection class derives from the BindingElementExtensionElement class. Die BindingElementType-Eigenschaft informiert das Konfigurationssystem über den Typ des für diesen Abschnitt zu erstellenden Bindungselements.The BindingElementType property informs the configuration system of the type of binding element to create for this section.

Alle von CustomTextMessageBindingElement definierten Einstellungen werden als Eigenschaften in CustomTextMessageEncodingBindingSection verfügbar gemacht.All of the settings defined by CustomTextMessageBindingElement are exposed as the properties in the CustomTextMessageEncodingBindingSection. Wenn ConfigurationPropertyAttribute nicht festgelegt wird, hilft dieses Attribut bei der Zuordnung der Konfigurationselementattribute zu den Eigenschaften und Einstellungsstandardwerten.The ConfigurationPropertyAttribute assists in mapping the configuration element attributes to the properties and setting default values if the attribute is not set. Nachdem die Werte aus der Konfiguration geladen und auf die Eigenschaften des Typs angewendet wurden, wird die CreateBindingElement-Methode aufgerufen, die die Eigenschaften in eine konkrete Instanz eines Bindungselements konvertiert.After the values from configuration are loaded and applied to the properties of the type, the CreateBindingElement method is called, which converts the properties into a concrete instance of a binding element.

Dieser Konfigurationshandler ordnet die folgende Darstellung in der App.config oder Web.config für den Dienst oder Client zu.This configuration handler maps to the following representation in the App.config or Web.config for the service or client.

<customTextMessageEncoding encoding="utf-8" contentType="text/xml" messageVersion="Soap11Addressing1" />  

In diesem Beispiel wird die ISO-8859-1-Codierung verwendet.The sample uses the ISO-8859-1 encoding.

Um diesen Konfigurationshandler zu verwenden, muss er mithilfe des folgenden Konfigurationselements registriert werden.To use this configuration handler it must be registered using the following configuration element.

<extensions>  
    <bindingElementExtensions>  
        <add name="customTextMessageEncoding" type="   
Microsoft.ServiceModel.Samples.CustomTextMessageEncodingBindingSection,   
                  CustomTextMessageEncoder" />  
    </bindingElementExtensions>  
</extensions>  

Siehe auchSee Also