Aracılığıyla paylaş


Özel İleti Kodlayıcı: Özel Metin Kodlayıcı

Metin örneği, Windows Communication Foundation (WCF) kullanarak özel bir metin iletisi kodlayıcının nasıl uygulanduğunu gösterir.

TextMessageEncodingBindingElement WCF yalnızca UTF-8, UTF-16 ve büyük endian Unicode kodlamalarını destekler. Bu örnekteki özel metin iletisi kodlayıcısı, birlikte çalışabilirlik için gerekli olabilecek tüm platform destekli karakter kodlamalarını destekler. Örnek bir istemci konsol programından (.exe), Internet Information Services (IIS) tarafından barındırılan bir hizmet kitaplığından (.dll) ve bir metin iletisi kodlayıcı kitaplığından (.dll) oluşur. Hizmet, istek-yanıt iletişim desenini tanımlayan bir sözleşme uygular. Sözleşme, matematik işlemlerini (Ekleme, Çıkarma, Çarpma ve Bölme) kullanıma sunan arabirim tarafından ICalculator tanımlanır. İstemci belirli bir matematik işlemine zaman uyumlu istekler yapar ve hizmet sonuçla yanıtlar. Hem istemci hem de hizmet varsayılan TextMessageEncodingBindingElementyerine öğesini CustomTextMessageEncoder kullanır.

Özel kodlayıcı uygulaması bir ileti kodlayıcı fabrikasından, ileti kodlayıcıdan, ileti kodlama bağlama öğesinden ve yapılandırma işleyiciden oluşur ve aşağıdakileri gösterir:

  • Özel kodlayıcı ve kodlayıcı fabrikası oluşturma.

  • Özel kodlayıcı için bağlama öğesi oluşturma.

  • Özel bağlama öğelerini tümleştirmek için özel bağlama yapılandırmasını kullanma.

  • Özel bağlama öğesinin dosya yapılandırmasına izin vermek için özel yapılandırma işleyicisi geliştirme.

Örneği ayarlamak, derlemek ve çalıştırmak için

  1. Aşağıdaki komutu kullanarak ASP.NET 4.0'ı yükleyin.

    %windir%\Microsoft.NET\Framework\v4.0.XXXXX\aspnet_regiis.exe /i /enable
    
  2. Windows Communication Foundation Örnekleri için Tek Seferlik Kurulum Yordamı'nı gerçekleştirdiğinizden emin olun.

  3. Çözümü oluşturmak için Windows Communication Foundation Örnekleri Oluşturma başlığındaki yönergeleri izleyin.

  4. Örneği tek veya makineler arası bir yapılandırmada çalıştırmak için Windows Communication Foundation Örneklerini Çalıştırma başlığındaki yönergeleri izleyin.

İleti Kodlayıcı Fabrikası ve İleti Kodlayıcı

ServiceHost veya istemci kanalı açıldığında, tasarım zamanı bileşeni CustomTextMessageBindingElement öğesini CustomTextMessageEncoderFactoryoluşturur. Fabrika, öğesini CustomTextMessageEncoderoluşturur. İleti kodlayıcı hem akış modunda hem de arabelleğe alınan modda çalışır. İletileri XmlReader sırasıyla okumak ve yazmak için ve XmlWriter kullanır. WcF'nin yalnızca UTF-8, UTF-16 ve big-endian Unicode'u destekleyen iyileştirilmiş XML okuyucularının ve yazarlarının aksine, bu okuyucular ve yazarlar platform tarafından desteklenen tüm kodlamayı destekler.

Aşağıdaki kod örneğinde CustomTextMessageEncoder gösterilmektedir.

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

Aşağıdaki kod örneği, ileti kodlayıcı fabrikasının nasıl der yapılacağını gösterir.

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

İleti Kodlama Bağlama Öğesi

Bağlama öğeleri WCF çalışma zamanı yığınının yapılandırılmasına izin verir. Bir WCF uygulamasında özel ileti kodlayıcısını kullanmak için, çalışma zamanı yığınında uygun düzeyde uygun ayarlarla ileti kodlayıcı fabrikasını oluşturan bir bağlama öğesi gerekir.

temel CustomTextMessageBindingElement sınıfından BindingElement türetilir ve sınıfından MessageEncodingBindingElement devralır. Bu, diğer WCF bileşenlerinin bu bağlama öğesini bir ileti kodlama bağlama öğesi olarak tanımasını sağlar. uygulaması CreateMessageEncoderFactory , uygun ayarlarla eşleşen ileti kodlayıcı fabrikasının bir örneğini döndürür.

CustomTextMessageBindingElement, ContentType, ve Encoding ayarlarını MessageVersionözellikler aracılığıyla kullanıma sunar. Kodlayıcı hem Soap11Addressing hem de Soap12Addressing1 sürümlerini destekler. Varsayılan değer Soap11Addressing1'dir. öğesinin ContentType varsayılan değeri "text/xml" değeridir. özelliği, Encoding istenen karakter kodlamasının değerini ayarlamanıza olanak tanır. Örnek istemci ve hizmet, WCF tarafından desteklenmeyen ISO-8859-1 (Latin1) karakter kodlamasını TextMessageEncodingBindingElement kullanır.

Aşağıdaki kod, özel metin iletisi kodlayıcısını kullanarak bağlamanın program aracılığıyla nasıl oluşturulacağını gösterir.

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

İleti Kodlama Bağlama Öğesine Meta Veri Desteği Ekleme

türetilen her tür, hizmet için oluşturulan WSDL belgesindeki SOAP bağlamasının sürümünü güncelleştirmekten MessageEncodingBindingElement sorumludur. Bu işlem, arabiriminde ExportEndpointIWsdlExportExtension yöntemi uygulanarak ve ardından oluşturulan WSDL değiştirilerek gerçekleştirilir. Bu örnekte, dosyasından CustomTextMessageBindingElement WSDL dışarı aktarma mantığını TextMessageEncodingBindingElementkullanır.

Bu örnek için istemci yapılandırması el ile yapılandırılır. İstemci yapılandırmasını oluşturmak için Svcutil.exe kullanamazsınız çünkü CustomTextMessageBindingElement , davranışını açıklamak için bir ilke onayını dışarı aktarmaz. Bağlama öğesi tarafından uygulanan davranışı veya özelliği açıklayan bir özel ilke onayını dışarı aktarmak için genellikle özel bir bağlama öğesinde arabirimini uygulamanız IPolicyExportExtension gerekir. Özel bağlama öğesi için ilke onayını dışarı aktarma örneği için bkz . Aktarım: UDP örneği.

İleti Kodlama Bağlama Yapılandırma İşleyicisi

Önceki bölümde özel metin iletisi kodlayıcısını program aracılığıyla nasıl kullanacağınız gösterilmektedir. , CustomTextMessageEncodingBindingSection bir yapılandırma dosyası içinde özel metin iletisi kodlayıcı kullanımını belirtmenize olanak tanıyan bir yapılandırma işleyicisi uygular. CustomTextMessageEncodingBindingSection sınıfı sınıfından BindingElementExtensionElement türetilir. özelliği, BindingElementType yapılandırma sistemine bu bölüm için oluşturulacak bağlama öğesinin türünü bildirir.

tarafından CustomTextMessageBindingElement tanımlanan tüm ayarlar içindeki CustomTextMessageEncodingBindingSectionözellikler olarak gösterilir. Yapılandırma ConfigurationPropertyAttribute öğesi özniteliklerini özelliklere eşleme ve öznitelik ayarlanmadıysa varsayılan değerleri ayarlama konusunda yardımcı olur. Yapılandırmadaki değerler yüklendikten ve türün özelliklerine uygulandıktan sonra, CreateBindingElement özellikleri bağlama öğesinin somut bir örneğine dönüştüren yöntemi çağrılır.

Bu yapılandırma işleyicisi, hizmet veya istemci için App.config veya Web.config dosyasında aşağıdaki gösterimle eşler.

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

Örnek ISO-8859-1 kodlamasını kullanır.

Bu yapılandırma işleyicisini kullanmak için aşağıdaki yapılandırma öğesi kullanılarak kaydedilmesi gerekir.

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