Bagikan melalui


Pengode Pesan Kustom: Pengode Teks Kustom

Sampel Teks menunjukkan cara mengimplementasikan encoder pesan teks kustom menggunakan Windows Communication Foundation (WCF).

TextMessageEncodingBindingElement WCF hanya mendukung pengodean Unicode UTF-8, UTF-16, dan big-endian. Encoder pesan teks kustom dalam sampel ini mendukung semua pengodean karakter yang didukung platform yang mungkin diperlukan untuk interoperabilitas. Sampel terdiri dari program konsol klien (.exe), pustaka layanan (.dll) yang dihosting oleh Internet Information Services (IIS), dan pustaka encoder pesan teks (.dll). Layanan ini menerapkan kontrak yang mendefinisikan pola komunikasi balasan permintaan. Kontrak didefinisikan oleh antarmuka ICalculator, yang mengekspos operasi matematika (Tambahkan, Kurangi, Kalikan, dan Bagi). Klien membuat permintaan sinkron ke operasi matematika tertentu dan layanan membalas dengan hasilnya. Klien dan layanan menggunakan CustomTextMessageEncoder alih-alih default TextMessageEncodingBindingElement.

Implementasi encoder kustom terdiri dari pabrik encoder pesan, encoder pesan, elemen pengodean pesan dan handler konfigurasi, dan menunjukkan hal berikut:

  • Membangun encoder kustom dan pabrik encoder.

  • Membuat elemen pengikatan untuk encoder kustom.

  • Menggunakan konfigurasi pengikatan kustom untuk mengintegrasikan elemen pengikatan kustom.

  • Mengembangkan handler konfigurasi kustom untuk memungkinkan konfigurasi elemen pengikatan kustom melalui file.

Untuk menyiapkan, mengompilasi, dan menjalankan sampel

  1. Instal ASP.NET 4.0 menggunakan perintah berikut.

    %windir%\Microsoft.NET\Framework\v4.0.XXXXX\aspnet_regiis.exe /i /enable
    
  2. Pastikan Anda telah melakukan Prosedur Penyiapan One-Time untuk Sampel Windows Communication Foundation.

  3. Untuk membangun solusi, ikuti instruksi dalam Membangun Sampel Windows Communication Foundation.

  4. Untuk menjalankan sampel dalam konfigurasi satu atau lintas komputer, ikuti instruksi di Menjalankan Sampel Windows Communication Foundation.

Pabrik Encoder Pesan dan Encoder Pesan

Ketika ServiceHost atau saluran klien dibuka, komponen CustomTextMessageBindingElement pada waktu desain membuat CustomTextMessageEncoderFactory. Pabrik membuat CustomTextMessageEncoder. Encoder pesan beroperasi baik dalam mode streaming maupun mode buffer. Ini menggunakan XmlReader dan XmlWriter untuk membaca dan menulis pesan masing-masing. Berbeda dengan pembaca dan penulis XML WCF yang dioptimalkan yang hanya mendukung UTF-8, UTF-16, dan Unicode big-endian, pembaca dan penulis ini mendukung semua pengodean yang didukung platform.

Contoh kode berikut menunjukkan 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 = $"{this.factory.MediaType}; charset={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();
    }
}

Contoh kode berikut menunjukkan cara membangun pabrik encoder pesan.

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;
        }
    }
}

Elemen Pengikatan Pengodean Pesan

Elemen pengikat memungkinkan konfigurasi tumpukan runtime WCF. Untuk menggunakan encoder pesan kustom dalam aplikasi WCF, elemen pengikatan diperlukan yang membuat pabrik encoder pesan dengan pengaturan yang sesuai pada tingkat yang sesuai dalam tumpukan runtime.

CustomTextMessageBindingElement berasal dari kelas dasar BindingElement dan mewarisi dari kelas MessageEncodingBindingElement. Ini memungkinkan komponen WCF lainnya mengenali elemen pengikatan ini sebagai elemen pengikatan pengodean pesan. Implementasi CreateMessageEncoderFactory mengembalikan instans pabrik encoder pesan yang cocok dengan pengaturan yang sesuai.

Pengaturan untuk CustomTextMessageBindingElement, MessageVersion, dan ContentType diekspos melalui properti Encoding. Encoder mendukung versi Soap11Addressing dan Soap12Addressing1. Defaultnya adalah Soap11Addressing1. Nilai defaultnya ContentType adalah "text/xml". Properti Encoding memungkinkan Anda untuk mengatur nilai pengodean karakter yang diinginkan. Klien sampel dan layanan menggunakan pengodean karakter ISO-8859-1 (Latin1), yang tidak didukung oleh TextMessageEncodingBindingElement WCF.

Kode berikut menunjukkan cara membuat pengikatan secara terprogram menggunakan encoder pesan teks kustom.

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);

Menambahkan Dukungan Metadata ke Elemen Binding Pengkodean Pesan

Jenis apa pun yang berasal dari MessageEncodingBindingElement bertanggung jawab untuk memperbarui versi pengikatan SOAP dalam dokumen WSDL yang dihasilkan untuk layanan. Ini dilakukan dengan menerapkan ExportEndpoint metode pada IWsdlExportExtension antarmuka dan kemudian memodifikasi WSDL yang dihasilkan. Dalam sampel ini, CustomTextMessageBindingElement menggunakan logika ekspor WSDL dari TextMessageEncodingBindingElement.

Untuk sampel ini, konfigurasi klien dikonfigurasi dengan tangan. Anda tidak dapat menggunakan Svcutil.exe untuk menghasilkan konfigurasi klien karena CustomTextMessageBindingElement tidak mengekspor pernyataan kebijakan untuk menjelaskan perilakunya. Anda umumnya harus menerapkan IPolicyExportExtension antarmuka pada elemen pengikatan kustom untuk mengekspor pernyataan kebijakan kustom yang menjelaskan perilaku atau kemampuan yang diterapkan oleh elemen pengikatan. Untuk contoh cara mengekspor pernyataan kebijakan untuk elemen pengikatan kustom, lihat sampel Transport: UDP .

Pengelola Konfigurasi Pengikatan Pengodean Pesan

Bagian sebelumnya memperlihatkan cara menggunakan encoder pesan teks kustom secara terprogram. CustomTextMessageEncodingBindingSection mengimplementasikan handler konfigurasi yang memungkinkan Anda menentukan penggunaan encoder pesan teks kustom dalam file konfigurasi. Kelas CustomTextMessageEncodingBindingSection ini berasal dari BindingElementExtensionElement kelas . Properti BindingElementType menginformasikan sistem konfigurasi jenis elemen pengikatan yang akan dibuat untuk bagian ini.

Semua pengaturan yang ditentukan oleh CustomTextMessageBindingElement diekspos sebagai properti di CustomTextMessageEncodingBindingSection. ConfigurationPropertyAttribute membantu dalam pemetaan atribut elemen konfigurasi ke properti dan menetapkan nilai default jika atribut tidak diatur. Setelah nilai dari konfigurasi dimuat dan diterapkan ke properti tipe, metode CreateBindingElement dipanggil, yang mengonversi properti menjadi instans konkret elemen pengikatan.

Handler konfigurasi ini memetakan ke representasi berikut di App.config atau Web.config untuk layanan atau klien.

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

Sampel menggunakan pengodean ISO-8859-1.

Untuk menggunakan handler konfigurasi ini, handler harus didaftarkan menggunakan elemen konfigurasi berikut.

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