Egyéni üzenetkódoló: Egyéni szövegkódoló

A Szöveg minta bemutatja, hogyan implementálhat egyéni szöveges üzenetkódolót a Windows Communication Foundation (WCF) használatával.

A TextMessageEncodingBindingElement WCF csak az UTF-8, az UTF-16 és a big endian Unicode kódolást támogatja. A mintában szereplő egyéni szöveges üzenetkódoló támogatja a platform által támogatott karakterkódolásokat, amelyek szükségesek lehetnek az együttműködéshez. A minta egy ügyfélkonzolprogramból (.exe), az Internet Information Services (IIS) által üzemeltetett szolgáltatástárból (.dll) és egy szöveges üzenetkódoló kódtárból (.dll) áll. A szolgáltatás megvalósít egy szerződést, amely egy kérés-válasz kommunikációs mintát határoz meg. A szerződést az ICalculator interfész határozza meg, amely matematikai műveleteket tesz elérhetővé (Hozzáadás, Kivonás, Szorzás és Osztás). Az ügyfél szinkron kéréseket küld egy adott matematikai művelethez, és a szolgáltatás az eredménnyel válaszol. Mind az ügyfél, mind a szolgáltatás az alapértelmezett CustomTextMessageEncoder helyett az TextMessageEncodingBindingElement-t használja.

Az egyéni kódoló implementációja egy üzenetkódoló-előállítóból, egy üzenetkódolóból, egy üzenetkódoló kötéselemből és egy konfigurációkezelőből áll, és a következőket mutatja be:

  • Egyéni kódoló és kódológyár létrehozása.

  • Kötéselem létrehozása egyéni kódolóhoz.

  • Egyéni kötési konfiguráció használata egyéni kötéselemek integrálásához.

  • Egyéni konfigurációkezelő fejlesztése egyéni kötéselemek fájlkonfigurációjának engedélyezéséhez.

A példa beállítása, elkészítése és futtatása

  1. Telepítse a ASP.NET 4.0-t az alábbi paranccsal.

    %windir%\Microsoft.NET\Framework\v4.0.XXXXX\aspnet_regiis.exe /i /enable
    
  2. Győződjön meg arról, hogy elvégezte a Windows Communication Foundation-minták One-Time beállítási eljárását.

  3. A megoldás létrehozásához kövesse a Windows Communication Foundation-minták készítésére vonatkozó utasításokat.

  4. Ha a mintát egy vagy több gép közötti konfigurációban szeretné futtatni, kövesse A Windows Communication Foundation-minták futtatásacímű témakör utasításait.

Message Encoder Factory és az Üzenetkódoló

Az ServiceHost vagy az ügyfélcsatorna megnyitásakor a tervezési idő komponens CustomTextMessageBindingElement létrehozza a CustomTextMessageEncoderFactory. A gyár létrehozza a CustomTextMessageEncoder. Az üzenetkódoló streamelési és pufferelt módban is működik. Az XmlReader és XmlWriter használja az üzenetek olvasására és írására. A WCF optimalizált XML-olvasóival és íróival szemben, amelyek csak az UTF-8, az UTF-16 és a big endian Unicode-ot támogatják, ezek az olvasók és írók támogatják az összes platform által támogatott kódolást.

Az alábbi példakód a CustomTextMessageEncodert mutatja be.

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

Az alábbi példakód bemutatja, hogyan hozhatja létre az üzenetkódoló-előállítót.

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

Üzenetkódolási kötéselem

A kötési elemek lehetővé teszik a WCF futtatókörnyezeti verem konfigurálását. Az egyéni üzenetkódoló WCF-alkalmazásokban való használatához kötési elem szükséges, amely létrehozza az üzenetkódoló-előállítót a megfelelő beállításokkal a futtatókörnyezeti verem megfelelő szintjén.

Az CustomTextMessageBindingElement osztály a BindingElement alaposztályból származik, és a MessageEncodingBindingElement osztálytól örökli. Ez lehetővé teszi, hogy más WCF-összetevők felismerjék ezt a kötési elemet üzenetkódoló kötéselemként. A megvalósítás CreateMessageEncoderFactory a megfelelő üzenetkódoló-előállító egy példányát adja vissza a megfelelő beállításokkal.

Az CustomTextMessageBindingElement elérhetővé teszi a beállításokat a MessageVersion, ContentTypeés Encoding a tulajdonságokon keresztül. A kódoló a Soap11Addressing és a Soap12Addressing1 verziót is támogatja. Az alapértelmezett a Soap11Addressing1. Az alapértelmezett érték a ContentType "text/xml". A Encoding tulajdonság lehetővé teszi a kívánt karakterkódolás értékének beállítását. A mintaügyfél és szolgáltatás az ISO-8859-1 (latin1) karakterkódolást használja, amelyet a TextMessageEncodingBindingElement WCF nem támogat.

Az alábbi kód bemutatja, hogyan hozhatja létre programozott módon a kötést az egyéni szöveges üzenetkódoló használatával.

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

Metaadatok támogatása az üzenetkódolási kötéselemhez

Bármely olyan típus, amely a MessageEncodingBindingElement-ből származik, felelős a szolgáltatáshoz létrehozott WSDL-dokumentumban a SOAP-kötés verziójának frissítéséért. Ehhez implementálja a ExportEndpoint metódust a IWsdlExportExtension felületen, majd módosítja a létrehozott WSDL-t. Ebben a példában a CustomTextMessageBindingElement a TextMessageEncodingBindingElement-ből származó WSDL exportálási logikát használja.

Ebben a mintában az ügyfélkonfiguráció kézzel van konfigurálva. Az ügyfélkonfiguráció létrehozásához nem használhatja a Svcutil.exe-t, mert a CustomTextMessageBindingElement nem exportál politikai kijelentést, hogy leírja a viselkedését. Egy egyéni kötési elem esetén implementálnia kell a IPolicyExportExtension felületet, hogy exportáljon egy, a kötési elem által implementált viselkedést vagy képességet leíró egyéni szabályzat-állítást. Az egyéni kötéselemekre vonatkozó házirend-állítás exportálására vonatkozó példát a Transport: UDP minta mutatja be.

Üzenetkódolási kötés konfigurációkezelője

Az előző szakasz bemutatja, hogyan használható programozott módon az egyéni szöveges üzenetkódoló. Az CustomTextMessageEncodingBindingSection implementál egy konfigurációkezelőt, amely lehetővé teszi egy egyéni szöveges üzenetkódoló használatát egy konfigurációs fájlon belül. Az CustomTextMessageEncodingBindingSection osztály az BindingElementExtensionElement osztályból származik. A BindingElementType tulajdonság tájékoztatja a konfigurációs rendszert a szakaszhoz létrehozandó kötési elem típusáról.

A CustomTextMessageBindingElement által meghatározott beállítások mindegyike a CustomTextMessageEncodingBindingSection tulajdonságaként jelenik meg. A ConfigurationPropertyAttribute konfigurációelem-attribútumok tulajdonságokhoz való leképezéséhez és alapértelmezett értékek beállításához nyújt segítséget, ha az attribútum nincs beállítva. A konfiguráció értékeinek betöltése és a típus tulajdonságaira való alkalmazása után a CreateBindingElement metódust meghívjuk, amely a tulajdonságokat egy kötéselem konkrét példányává alakítja.

Ez a konfigurációkezelő a szolgáltatás vagy ügyfél App.config vagy Web.config a következő ábrázolásra képez le.

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

A minta az ISO-8859-1 kódolást használja.

A konfigurációkezelő használatához a következő konfigurációs elem használatával kell regisztrálni.

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