Megosztás a következőn keresztül:


Az üzenetosztály használata

Az Message osztály alapvető fontosságú a Windows Communication Foundation (WCF) számára. Az ügyfelek és szolgáltatások közötti kommunikáció végső soron a példányok küldését és fogadását eredményezi Message .

Általában nem lép kapcsolatba közvetlenül az Message osztálysal. Ehelyett a WCF szolgáltatásmodell-szerkezetek, például az adatszerződések, az üzenetszerződések és a műveleti szerződések a bejövő és kimenő üzenetek leírására szolgálnak. Bizonyos speciális helyzetekben azonban közvetlenül az Message osztály használatával programozott. Használhatja például az osztályt Message :

  • Ha a kimenő üzenetek tartalmának létrehozására (például közvetlenül egy lemezen lévő fájlból) van szüksége egy másik módszerre ahelyett, hogy .NET-keretrendszer objektumokat szerializál.

  • Ha a bejövő üzenetek tartalmának alternatív módjára van szüksége (például ha XSLT-átalakítást szeretne alkalmazni a nyers XML-tartalomra), ahelyett, hogy deszerializálna .NET-keretrendszer objektumokba.

  • Ha az üzeneteket az üzenet tartalmától függetlenül általánosan kell kezelnie (például útválasztó, terheléselosztó vagy közzétételi előfizető rendszer létrehozásakor az üzenetek átirányítása vagy továbbítása során).

Az Message osztály használata előtt ismerkedjen meg a WCF adatátviteli architektúrájával az adatátviteli architektúra áttekintésében.

Az A Message az adatok általános célú tárolója, de kialakítása szorosan követi a SOAP protokollban lévő üzenet kialakítását. A SOAP-hez hasonlóan az üzenetek törzse és fejlécei is vannak. Az üzenet törzse tartalmazza a tényleges hasznos adatokat, míg a fejlécek további elnevezett adattárolókat tartalmaznak. A törzs és a fejlécek olvasására és írására vonatkozó szabályok eltérőek, például a fejlécek mindig pufferelve vannak a memóriában, és tetszőleges sorrendben érhetők el, míg a törzs csak egyszer olvasható és streamelhető. A SOAP használatakor az üzenet törzse általában a SOAP törzsre van leképezve, az üzenetfejlécek pedig a SOAP-fejlécekre vannak leképezve.

Az üzenetosztály használata a műveletekben

Az osztályt Message használhatja egy művelet bemeneti paramétereként, egy művelet visszatérési értékeként vagy mindkettőként. Ha Message egy műveletben bárhol használják, a következő korlátozások érvényesek:

  • A művelet nem rendelkezhet paraméterekkel vagy ref paraméterekkelout.

  • Egynél input több paraméter nem lehet. Ha a paraméter jelen van, üzenetnek vagy üzenetszerződés-típusnak kell lennie.

  • A visszatérési típusnak vagy voidaz Messageüzenetszerződés típusának kell lennie.

Az alábbi példakód érvényes műveleti szerződést tartalmaz.

[ServiceContract]
public interface IMyService
{
    [OperationContract]
    Message GetData();

    [OperationContract]
    void PutData(Message m);
}
<ServiceContract()> _
Public Interface IMyService
    <OperationContract()> _
    Function GetData() As Message

    <OperationContract()> _
    Sub PutData(ByVal m As Message)
End Interface

Egyszerű üzenetek létrehozása

Az Message osztály statikus CreateMessage gyári metódusokat biztosít, amelyekkel alapszintű üzeneteket hozhat létre.

Minden CreateMessage túlterhelés olyan verzióparamétert MessageVersion használ, amely jelzi az üzenethez használni kívánt SOAP és WS-Addressing verziókat. Ha ugyanazokat a protokollverziókat szeretné használni, mint a bejövő üzenet, használhatja a IncomingMessageVersion tulajdonságból beszerzett példány tulajdonságát OperationContext Current . A legtöbb CreateMessage túlterhelésnek van egy sztringparamétere is, amely az üzenethez használni kívánt SOAP-műveletet jelzi. A verzió beállítható úgy, hogy letiltsa a None SOAP-borítékok létrehozását. Az üzenet csak a törzsből áll.

Üzenetek létrehozása objektumokból

A legalapvetőbb CreateMessage túlterhelés, amely csak egy verziót és egy műveletet vesz igénybe, üres törzsű üzenetet hoz létre. Egy másik túlterhelés további Object paramétert vesz igénybe; ez létrehoz egy üzenetet, amelynek törzse az adott objektum szerializált ábrázolása. A szerializáláshoz használja az DataContractSerializer alapértelmezett beállításokat. Ha másik szerializálót szeretne használni, vagy másképpen szeretné konfigurálni, DataContractSerializer használja azt a CreateMessage túlterhelést, amely egy paramétert XmlObjectSerializer is használ.

Ha például egy objektumot szeretne visszaadni egy üzenetben, használhatja az alábbi kódot.

public class MyService1 : IMyService
{
    public Message GetData()
    {
        Person p = new Person();
        p.name = "John Doe";
        p.age = 42;
        MessageVersion ver = OperationContext.Current.IncomingMessageVersion;
        return Message.CreateMessage(ver, "GetDataResponse", p);
    }

    public void PutData(Message m)
    {
        // Not implemented.
    }
}
[DataContract]
public class Person
{
    [DataMember] public string name;
    [DataMember] public int age;
}
Public Class MyService1
    Implements IMyService

    Public Function GetData() As Message _
     Implements IMyService.GetData
        Dim p As New Person()
        p.name = "John Doe"
        p.age = 42
        Dim ver As MessageVersion = _
          OperationContext.Current.IncomingMessageVersion
        Return Message.CreateMessage(ver, "GetDataResponse", p)

    End Function


    Public Sub PutData(ByVal m As Message) _
    Implements IMyService.PutData
        ' Not implemented.
    End Sub
End Class
<DataContract()> _
Public Class Person
    <DataMember()> _
    Public name As String
    <DataMember()> _
    Public age As Integer
End Class

Üzenetek létrehozása XML-olvasókból

Vannak CreateMessage olyan túlterhelések, amelyek egy objektum helyett egy XmlReader vagy egy XmlDictionaryReader testet vesznek igénybe. Ebben az esetben az üzenet törzse tartalmazza azt az XML-t, amely az átadott XML-olvasóból való olvasásból származik. Az alábbi kód például egy XML-fájlból beolvasott törzstartalommal rendelkező üzenetet ad vissza.

public class MyService2 : IMyService
{
    public Message GetData()
    {
        FileStream stream = new FileStream("myfile.xml",FileMode.Open);
        XmlDictionaryReader xdr =
               XmlDictionaryReader.CreateTextReader(stream,
                           new XmlDictionaryReaderQuotas());
        MessageVersion ver =
            OperationContext.Current.IncomingMessageVersion;
        return Message.CreateMessage(ver,"GetDataResponse",xdr);
    }

    public void PutData(Message m)
    {
        // Not implemented.
    }
}
Public Class MyService2
    Implements IMyService

    Public Function GetData() As Message Implements IMyService.GetData
        Dim stream As New FileStream("myfile.xml", FileMode.Open)
        Dim xdr As XmlDictionaryReader = _
        XmlDictionaryReader.CreateTextReader(stream, New XmlDictionaryReaderQuotas())
        Dim ver As MessageVersion = OperationContext.Current.IncomingMessageVersion
        Return Message.CreateMessage(ver, "GetDataResponse", xdr)

    End Function


    Public Sub PutData(ByVal m As Message) Implements IMyService.PutData

    End Sub
End Class

Emellett vannak CreateMessage túlterhelések, amelyek a XmlReader XmlDictionaryReader teljes üzenetet és nem csak a törzset jelölik. Ezek a túlterhelések egész paramétert maxSizeOfHeaders is vesznek igénybe. A fejlécek mindig pufferelve lesznek a memóriába az üzenet létrehozása után, és ez a paraméter korlátozza a pufferelés mennyiségét. Fontos, hogy ezt a paramétert biztonságos értékre állítsa, ha az XML nem megbízható forrásból származik, hogy mérsékelje a szolgáltatásmegtagadásos támadás lehetőségét. Az XML-olvasó által képviselt üzenet SOAP és WS-Addressing verzióinak meg kell egyezniük a verzióparaméterrel jelzett verziókkal.

Üzenetek létrehozása a BodyWriter használatával

Egy CreateMessage túlterhelés egy BodyWriter példányt vesz igénybe az üzenet törzsének leírásához. Az A BodyWriter egy absztrakt osztály, amely az üzenettörzsek létrehozásának testreszabására használható. Létrehozhat saját BodyWriter származtatott osztályt az üzenettörzsek egyéni leírásához. Felül kell bírálnia a BodyWriter.OnWriteBodyContents metódust XmlDictionaryWriter, amely egy ; ez a módszer felelős a törzs írásáért.

A törzsírók pufferelhetők vagy nem pufferelhetők (streamelhetők). A pufferelt szövegtörzs-írók tetszőleges számú alkalommal írhatják ki a tartalmukat, míg a streameltek csak egyszer írhatják ki a tartalmukat. A IsBuffered tulajdonság azt jelzi, hogy a szövegtörzs-író pufferelt-e vagy sem. Ezt a törzsíróhoz úgy állíthatja be, hogy meghívja a logikai paramétert használó védett BodyWriter konstruktort isBuffered . A testírók támogatják a pufferelt testírók létrehozását nem pufferelt testírókból. A folyamat testreszabásához felülbírálhatja a OnCreateBufferedCopy metódust. Alapértelmezés szerint a rendszer egy memóriabeli puffert használ, amely a visszaadott OnWriteBodyContents XML-t tartalmazza. OnCreateBufferedCopy egész szám paramétert maxBufferSize használ; ha felülbírálja ezt a módszert, nem szabad ennél nagyobb puffereket létrehoznia.

Az BodyWriter osztály biztosítja azokat a WriteBodyContents metódusokat és CreateBufferedCopy metódusokat, amelyek lényegében vékony burkolók OnWriteBodyContents és OnCreateBufferedCopy metódusok. Ezek a metódusok állapotellenőrzést végeznek annak érdekében, hogy a nem pufferelt szövegtörzs-írók ne férhessenek hozzá többször. Ezeket a metódusokat közvetlenül csak akkor hívjuk meg, ha egyéni Message származtatott osztályokat hozunk létre az alapján BodyWriters.

Hibaüzenetek létrehozása

Bizonyos CreateMessage túlterhelések használatával SOAP-hibaüzeneteket hozhat létre. Ezek közül a legalapvetőbb a MessageFault hibát leíró objektum. Más túlterhelések is biztosítottak a kényelem érdekében. Az első ilyen túlterhelés egy és egy ok sztringet FaultCode vesz igénybe, és létrehoz egy MessageFault ilyen MessageFault.CreateFault információt használó karakterláncot. A másik túlterhelés egy részletes objektumot vesz igénybe, és a hibakóddal és az okokkal együtt továbbítja CreateFault azt. Az alábbi művelet például hibát ad vissza.

public class MyService3 : IMyService
{
    public Message GetData()
    {
        FaultCode fc = new FaultCode("Receiver");
        MessageVersion ver = OperationContext.Current.IncomingMessageVersion;
            return Message.CreateMessage(ver,fc,"Bad data","GetDataResponse");
    }

    public void PutData(Message m)
    {
        // Not implemented.
    }
}
Public Class MyService3
    Implements IMyService

    Public Function GetData() As Message Implements IMyService.GetData
        Dim fc As New FaultCode("Receiver")
        Dim ver As MessageVersion = OperationContext.Current.IncomingMessageVersion
        Return Message.CreateMessage(ver, fc, "Bad data", "GetDataResponse")

    End Function


    Public Sub PutData(ByVal m As Message) Implements IMyService.PutData

    End Sub
End Class

Üzenettörzs adatainak kinyerése

Az Message osztály többféle módon is képes kinyerni az információkat a törzséből. Ezek a következő kategóriákba sorolhatók be:

  • A teljes üzenettörzset egyszerre kell kiírnia egy XML-írónak. Ezt üzenet írásának nevezzük.

  • XML-olvasó lekérése az üzenet törzsén. Ez lehetővé teszi, hogy később szükség szerint, darabonként hozzáférjen az üzenet törzséhez. Ezt üzenet olvasásának nevezzük.

  • A teljes üzenet, beleértve a törzsét is, átmásolható egy MessageBuffer ilyen típusú memóriabeli pufferbe. Ezt nevezzük üzenet másolásának.

A törzs Message csak egyszer érhető el, függetlenül attól, hogy hogyan érhető el. Az üzenetobjektumok State tulajdonsága kezdetben Létrehozás értékre van állítva. Az előző listában ismertetett három hozzáférési módszer írási, olvasási és másolási állapotot állít be. Emellett egy Close metódus akkor is bezárt állapotba állíthatja az állapotot, ha már nincs szükség az üzenet törzsének tartalmára. Az üzenet törzse csak a Létrehozott állapotban érhető el, és az állapot módosítása után nem lehet visszamenni a Létrehozott állapotba.

Üzenetek írása

A WriteBodyContents(XmlDictionaryWriter) metódus egy adott Message példány törzstartalmat ír ki egy adott XML-írónak. A WriteBody módszer ugyanezt teszi, azzal a kivételsel, hogy a törzs tartalmát a megfelelő burkolóelembe (például <soap:body>) csomagolja. WriteMessage Végül írja ki a teljes üzenetet, beleértve a burkoló SOAP borítékot és a fejléceket. Ha a SOAP ki van kapcsolva (Version is MessageVersion.None), mindhárom módszer ugyanezt teszi: kiírják az üzenet törzsének tartalmát.

Az alábbi kód például egy bejövő üzenet törzsét írja ki egy fájlba.

public class MyService4 : IMyService
{
    public void PutData(Message m)
    {
        FileStream stream = new FileStream("myfile.xml",FileMode.Create);
        XmlDictionaryWriter xdw =
            XmlDictionaryWriter.CreateTextWriter(stream);
        m.WriteBodyContents(xdw);
        xdw.Flush();
    }

    public Message GetData()
    {
        throw new NotImplementedException();
    }
}
Public Class MyService4
    Implements IMyService

    Public Sub PutData(ByVal m As Message) Implements IMyService.PutData
        Dim stream As New FileStream("myfile.xml", FileMode.Create)
        Dim xdw As XmlDictionaryWriter = XmlDictionaryWriter.CreateTextWriter(stream)
        m.WriteBodyContents(xdw)
        xdw.Flush()

    End Sub


    Public Function GetData() As Message Implements IMyService.GetData
        Throw New NotImplementedException()

    End Function
End Class

Két további segítő módszer ír ki bizonyos SOAP kezdőelem-címkéket. Ezek a metódusok nem férnek hozzá az üzenet törzséhez, ezért nem módosítják az üzenet állapotát. Ezek közé tartoznak:

A megfelelő záróelemcímkék írásához hívja meg WriteEndElement a megfelelő XML-írót. Ezeket a metódusokat ritkán nevezik közvetlenül.

Üzenetek olvasása

Az üzenettörzs olvasásának elsődleges módja a hívás GetReaderAtBodyContents. Egy olyan üzenetet kap vissza XmlDictionaryReader , amellyel elolvashatja az üzenet törzsét. Vegye figyelembe, hogy az Message áttűnés az olvasási állapotra a hívás után azonnal GetReaderAtBodyContents történik, és nem a visszaadott XML-olvasó használatakor.

A GetBody metódus lehetővé teszi az üzenet törzsének gépelt objektumként való elérését is. Ez a metódus belsőleg használja GetReaderAtBodyContents, így az üzenet állapotát is áttűni az Read állapotra (lásd a tulajdonságot State ).

Érdemes ellenőrizni a IsEmpty tulajdonságot, ebben az esetben az üzenettörzs üres, és GetReaderAtBodyContents dob egy InvalidOperationException. Ha ez egy fogadott üzenet (például a válasz), érdemes lehet ellenőrizni IsFaultis, amely jelzi, hogy az üzenet tartalmaz-e hibát.

A deszerializálás legalapvetőbb túlterhelése GetBody egy (az általános paraméter által jelzett) DataContractSerializer típuspéldányba alakítja az üzenettörzset az alapértelmezett beállításokkal konfigurált és a MaxItemsInObjectGraph kvóta letiltásával. Ha másik szerializációs motort szeretne használni, vagy nem alapértelmezett módon szeretné konfigurálni, DataContractSerializer használja a GetBody túlterhelést, amely egy XmlObjectSerializer.

Az alábbi kód például adatokat nyer ki egy szerializált Person objektumot tartalmazó üzenettörzsből, és kinyomtatja a személy nevét.

    public class MyService5 : IMyService
    {
        public void PutData(Message m)
        {
            Person p = m.GetBody<Person>();
            Console.WriteLine(p.name);
        }

        public Message GetData()
        {
            throw new NotImplementedException();
        }
    }
}
namespace Samples2
{
    [ServiceContract]
    public interface IMyService
    {
        [OperationContract]
        Message GetData();

        [OperationContract]
        void PutData(Message m);
    }

    [DataContract]
    public class Person
    {
        [DataMember] public string name;
        [DataMember] public int age;
    }
    Public Class MyService5
        Implements IMyService

        Public Sub PutData(ByVal m As Message) Implements IMyService.PutData
            Dim p As Person = m.GetBody(Of Person)()
            Console.WriteLine(p.name)

        End Sub


        Public Function GetData() As Message Implements IMyService.GetData
            Throw New NotImplementedException()

        End Function
    End Class
End Namespace
Namespace Samples2
    <ServiceContract()> _
    Public Interface IMyService
        <OperationContract()> _
        Function GetData() As Message

        <OperationContract()> _
        Sub PutData(ByVal m As Message)
    End Interface

    <DataContract()> _
    Public Class Person
        <DataMember()> _
        Public name As String
        <DataMember()> _
        Public age As Integer
    End Class

Üzenet másolása pufferbe

Előfordulhat, hogy többször is hozzá kell férni az üzenet törzséhez, például egy közzétevő-előfizető rendszer részeként ugyanazt az üzenetet több célhelyre kell továbbítani. Ebben az esetben a teljes üzenetet (beleértve a törzset) pufferelni kell a memóriában. Ezt a hívással CreateBufferedCopy(Int32)teheti meg. Ez a metódus egy egész szám paramétert használ, amely a maximális pufferméretet jelöli, és létrehoz egy olyan puffert, amely nem nagyobb ennél a méretnél. Fontos, hogy ezt biztonságos értékre állítsa, ha az üzenet nem megbízható forrásból származik.

A puffer példányként lesz visszaadva MessageBuffer . A pufferben lévő adatokat többféleképpen is elérheti. Az elsődleges módszer a CreateMessage példányok pufferből való létrehozása Message .

A pufferben lévő adatok elérésének másik módja az osztály által MessageBuffer implementálható felület implementálása IXPathNavigable az alapul szolgáló XML közvetlen eléréséhez. Egyes CreateNavigator túlterhelések lehetővé teszik a csomópontkvóta által védett kezelők létrehozását System.Xml.XPath , korlátozva a látogatható XML-csomópontok számát. Ez segít megelőzni a szolgáltatásmegtagadási támadásokat a hosszú feldolgozási idő alapján. Ez az ajánlat alapértelmezés szerint le van tiltva. Egyes CreateNavigator túlterhelések lehetővé teszik, hogy megadhatja, hogyan kell kezelni a szabad területet az XML-ben az XmlSpace enumerálás használatával, az alapértelmezett érték pedig XmlSpace.Nonea .

Az üzenetpuffer tartalmának elérésének végső módja az, ha a tartalmát egy streambe írja ki a használatával WriteMessage.

Az alábbi példa bemutatja, hogy a MessageBufferrendszer egy bejövő üzenetet több címzettnek továbbít, majd egy fájlba naplóz. Pufferelés nélkül ez nem lehetséges, mert az üzenet törzse csak egyszer érhető el.

[ServiceContract]
public class ForwardingService
{
    private List<IOutputChannel> forwardingAddresses;

    [OperationContract]
    public void ForwardMessage (Message m)
    {
        //Copy the message to a buffer.
        MessageBuffer mb = m.CreateBufferedCopy(65536);

        //Forward to multiple recipients.
        foreach (IOutputChannel channel in forwardingAddresses)
        {
            Message copy = mb.CreateMessage();
            channel.Send(copy);
        }

        //Log to a file.
        FileStream stream = new FileStream("log.xml",FileMode.Append);
        mb.WriteMessage(stream);
        stream.Flush();
    }
}
<ServiceContract()> _
Public Class ForwardingService
    Private forwardingAddresses As List(Of IOutputChannel)

    <OperationContract()> _
    Public Sub ForwardMessage(ByVal m As Message)
        'Copy the message to a buffer.
        Dim mb As MessageBuffer = m.CreateBufferedCopy(65536)

        'Forward to multiple recipients.
        Dim channel As IOutputChannel
        For Each channel In forwardingAddresses
            Dim copy As Message = mb.CreateMessage()
            channel.Send(copy)
        Next channel

        'Log to a file.
        Dim stream As New FileStream("log.xml", FileMode.Append)
        mb.WriteMessage(stream)
        stream.Flush()

    End Sub
End Class

Az MessageBuffer osztálynak más tagjai is vannak, érdemes megjegyezni. A Close metódus meghívható erőforrások felszabadítására, ha már nincs szükség a puffer tartalmára. A BufferSize tulajdonság a lefoglalt puffer méretét adja vissza. A MessageContentType tulajdonság az üzenet MIME-tartalomtípusát adja vissza.

Az üzenettörzs elérése hibakereséshez

Hibakeresés céljából meghívhatja a metódust, ToString hogy sztringként ábrázolja az üzenetet. Ez az ábrázolás általában megegyezik azzal, ahogyan egy üzenet a vezetéken nézne, ha a szövegkódolóval lenne kódolva, azzal a kivétellel, hogy az XML jobban formázható lenne az emberi olvashatóság érdekében. Ez alól az egyetlen kivétel az üzenet törzse. A törzs csak egyszer olvasható, és ToString nem módosítja az üzenet állapotát. Ezért előfordulhat, hogy a ToString metódus nem fér hozzá a törzshez, és helyettesítheti a helyőrzőt (például "..." vagy három pont) az üzenet törzse helyett. Ezért ne használja ToString az üzenetek naplózását, ha az üzenetek törzstartalma fontos.

Egyéb üzenetrészek elérése

A rendszer különböző tulajdonságokat biztosít az üzenet információinak eléréséhez a törzs tartalmától eltérően. Ezek azonban nem hívhatók meg az üzenet bezárása után:

  • A Headers tulajdonság az üzenetfejléceket jelöli. A témakör későbbi részében a "Fejlécek használata" című szakaszt tekinti meg.

  • A Properties tulajdonság az üzenet tulajdonságait jelöli, amelyek az üzenethez csatolt elnevezett adatok, amelyek általában nem lesznek kibocsátva az üzenet elküldésekor. Tekintse meg a témakör későbbi részében a "Tulajdonságok használata" című szakaszt.

  • A Version tulajdonság az üzenethez társított SOAP és WS-Addressing verziót jelzi, vagy None ha a SOAP le van tiltva.

  • A IsFault tulajdonság akkor ad true vissza, ha az üzenet SOAP-hibaüzenet.

  • A IsEmpty tulajdonság akkor ad true vissza, ha az üzenet üres.

A metódussal GetBodyAttribute(String, String) hozzáférhet egy adott névvel és névtérrel azonosított törzsburkoló elemhez (például <soap:Body>) egy adott attribútumhoz. Ha nem található ilyen attribútum, null a rendszer visszaadja. Ez a metódus csak akkor hívható meg, ha a Message rendszer a Létrehozott állapotban van (ha az üzenet törzse még nem érhető el).

Élőfejek használata

Az A Message tetszőleges számú elnevezett XML-szilánkot, úgynevezett fejlécet tartalmazhat. Minden töredék általában soap fejlécre van leképezett állapotban. A fejlécek a Headers típus MessageHeaderstulajdonságán keresztül érhetők el. MessageHeaders objektumgyűjtemény MessageHeaderInfo , és az egyes fejlécek a felületén IEnumerable vagy az indexelőn keresztül érhetők el. Az alábbi kód például a fejlécek nevét sorolja fel.Message

public class MyService6 : IMyService
{
    public void PutData(Message m)
    {
        foreach (MessageHeaderInfo mhi in m.Headers)
        {
            Console.WriteLine(mhi.Name);
        }
    }

    public Message GetData()
    {
        throw new NotImplementedException();
    }
}
Public Class MyService6
    Implements IMyService

    Public Sub PutData(ByVal m As Message) Implements IMyService.PutData
        Dim mhi As MessageHeaderInfo
        For Each mhi In m.Headers
            Console.WriteLine(mhi.Name)
        Next mhi

    End Sub


    Public Function GetData() As Message Implements IMyService.GetData
        Throw New NotImplementedException()

    End Function
End Class

Élőfejek hozzáadása, eltávolítása, keresése

A metódussal Add új fejlécet adhat hozzá az összes meglévő fejléc végéhez. A metódussal Insert beszúrhat egy fejlécet egy adott indexbe. A program áthelyezi a meglévő fejléceket a beszúrt elemhez. A fejlécek az indexük szerint vannak rendezve, az első elérhető index pedig a 0. A különböző CopyHeadersFrom metódustúlterheltségekkel fejléceket vehet fel egy másik Message vagy MessageHeaders példányból. Egyes túlterhelések egyetlen élőfejet másolnak, míg mások mindegyiket másolják. A Clear metódus eltávolítja az összes fejlécet. A RemoveAt metódus eltávolít egy fejlécet egy adott indexen (az összes fejlécet eltolja utána). A RemoveAll metódus eltávolítja az adott névvel és névtérrel rendelkező összes fejlécet.

Egy adott fejléc lekérése a FindHeader módszerrel. Ez a metódus a fejléc nevét és névterét keresi, és visszaadja annak indexét. Ha a fejléc többször is előfordul, a rendszer kivételt jelez. Ha a fejléc nem található, az -1 értéket adja vissza.

A SOAP-fejlécmodellben az élőfejek olyan értékkel rendelkezhetnek Actor , amely meghatározza a fejléc kívánt címzettjének nevét. A legalapvetőbb FindHeader túlterhelés csak az üzenet végső címzettjének szánt fejléceket keresi. Egy másik túlterhelés azonban lehetővé teszi annak megadását, hogy mely Actor értékek szerepelnek a keresésben. További információkért lásd a SOAP specifikációját.

A CopyTo(MessageHeaderInfo[], Int32) rendszer metódust biztosít az élőfejek gyűjteményből MessageHeaders egy objektumtömbbe való másolásához MessageHeaderInfo .

Az XML-adatok fejlécben való eléréséhez meghívhat GetReaderAtHeader és visszaadhat egy XML-olvasót az adott fejlécindexhez. Ha a fejléc tartalmát objektummá szeretné deszerializálni, használja GetHeader<T>(Int32) vagy a többi túlterhelés egyikét. A legalapvetőbb túlterhelések az alapértelmezett módon konfigurált módon deszerializálják a fejléceket DataContractSerializer . Ha másik szerializálót vagy más konfigurációt DataContractSerializerszeretne használni, használja az egyik túlterhelést, amely egy XmlObjectSerializer. Vannak túlterhelések is, amelyek a fejléc nevét, a névteret és opcionálisan az értékek listáját Actor használják index helyett; ez a kombináció FindHeader és GetHeadera .

Tulajdonságok használata

A Message példányok tetszőleges számú tetszőleges típusú elnevezett objektumot tartalmazhatnak. Ez a gyűjtemény a Properties típustulajdonságon MessagePropertieskeresztül érhető el. A gyűjtemény implementálja az IDictionary<TKey,TValue> interfészt, és leképezésként működik.ObjectString A tulajdonságértékek általában nem képezhetők közvetlenül a vezetéken lévő üzenet egyik részéhez sem, hanem különböző üzenetfeldolgozási tippeket nyújtanak a WCF-csatorna verem különböző csatornáihoz vagy a CopyTo(MessageHeaderInfo[], Int32) szolgáltatási keretrendszerhez. Példa: Adatátviteli architektúra áttekintése.

Öröklődés az üzenetosztályból

Ha a beépített üzenettípusok nem CreateMessage felelnek meg a követelményeknek, hozzon létre egy osztályt, amely az Message osztályból származik.

Az üzenettörzs tartalmának meghatározása

Az üzenettörzsben lévő adatok eléréséhez három elsődleges technika létezik: írás, olvasás és másolás egy pufferbe. Ezek a műveletek végül azt eredményezik, OnGetReaderAtBodyContentshogy a OnWriteBodyContentsmetódusok neve OnCreateBufferedCopy a származtatott osztályon Messagelesz. Az alaposztály Message garantálja, hogy az egyes Message példányokhoz csak az egyik metódust hívja meg, és hogy a rendszer csak egyszer hívja meg. Az alaposztály azt is biztosítja, hogy a metódusok ne legyenek zárt üzenetben meghívva. Nincs szükség az üzenet állapotának nyomon követésére a megvalósításban.

OnWriteBodyContents absztrakciós módszer, amelyet végre kell hajtani. Az üzenet törzstartalmának meghatározásának legalapvetőbb módja az írás ezzel a módszerrel. Az alábbi üzenet például 100 000 véletlenszerű számot tartalmaz 1 és 20 között.

public class RandomMessage : Message
{
    override protected  void  OnWriteBodyContents(XmlDictionaryWriter writer)
    {
        Random r = new Random();
        for (int i = 0; i <100000; i++)
        {
            writer.WriteStartElement("number");
            writer.WriteValue(r.Next(1,20));
            writer.WriteEndElement();
        }
    }
    //code omitted…
Public Class RandomMessage
    Inherits Message

    Protected Overrides Sub OnWriteBodyContents( _
            ByVal writer As XmlDictionaryWriter)
        Dim r As New Random()
        Dim i As Integer
        For i = 0 To 99999
            writer.WriteStartElement("number")
            writer.WriteValue(r.Next(1, 20))
            writer.WriteEndElement()
        Next i

    End Sub
    ' Code omitted.

A OnGetReaderAtBodyContents() metódusok és OnCreateBufferedCopy az alapértelmezett implementációk a legtöbb esetben működnek. Az alapértelmezett implementációk meghívják OnWriteBodyContents, pufferelik az eredményeket, és együttműködnek az eredményként kapott pufferrel. Bizonyos esetekben azonban ez nem elegendő. Az előző példában az üzenet olvasása 100 000 XML-elem pufferelését eredményezi, ami nem feltétlenül kívánatos. Érdemes lehet felülbírálni OnGetReaderAtBodyContents() egy egyéni XmlDictionaryReader származtatott osztályt, amely véletlenszerű számokat szolgál ki. Ezt követően felülbírálhatja OnWriteBodyContents a metódus által visszaadott olvasó OnGetReaderAtBodyContents() használatát az alábbi példában látható módon.

    public override MessageHeaders Headers
    {
        get { throw new Exception("The method or operation is not implemented."); }
    }

    public override MessageProperties Properties
    {
        get { throw new Exception("The method or operation is not implemented."); }
    }

    public override MessageVersion Version
    {
        get { throw new Exception("The method or operation is not implemented."); }
    }
}

public class RandomMessage2 : Message
{
    override protected XmlDictionaryReader OnGetReaderAtBodyContents()
    {
    return new RandomNumbersXmlReader();
    }

    override protected void OnWriteBodyContents(XmlDictionaryWriter writer)
    {
        XmlDictionaryReader xdr = OnGetReaderAtBodyContents();
        writer.WriteNode(xdr, true);
    }
    public override MessageHeaders Headers
    {
        get { throw new Exception("The method or operation is not implemented."); }
    }

    public override MessageProperties Properties
    {
        get { throw new Exception("The method or operation is not implemented."); }
    }

    public override MessageVersion Version
    {
        get { throw new Exception("The method or operation is not implemented."); }
    }
}

public class RandomNumbersXmlReader : XmlDictionaryReader
{
    //code to serve up 100000 random numbers in XML form omitted…

    Public Overrides ReadOnly Property Headers() As MessageHeaders
        Get
            Throw New Exception("The method or operation is not implemented.")
        End Get
    End Property

    Public Overrides ReadOnly Property Properties() As MessageProperties
        Get
            Throw New Exception("The method or operation is not implemented.")
        End Get
    End Property

    Public Overrides ReadOnly Property Version() As MessageVersion
        Get
            Throw New Exception("The method or operation is not implemented.")
        End Get
    End Property
End Class

Public Class RandomMessage2
    Inherits Message

    Protected Overrides Function OnGetReaderAtBodyContents() As XmlDictionaryReader
        Return New RandomNumbersXmlReader()

    End Function


    Protected Overrides Sub OnWriteBodyContents(ByVal writer As XmlDictionaryWriter)
        Dim xdr As XmlDictionaryReader = OnGetReaderAtBodyContents()
        writer.WriteNode(xdr, True)

    End Sub

    Public Overrides ReadOnly Property Headers() As MessageHeaders
        Get
            Throw New Exception("The method or operation is not implemented.")
        End Get
    End Property

    Public Overrides ReadOnly Property Properties() As MessageProperties
        Get
            Throw New Exception("The method or operation is not implemented.")
        End Get
    End Property

    Public Overrides ReadOnly Property Version() As MessageVersion
        Get
            Throw New Exception("The method or operation is not implemented.")
        End Get
    End Property
End Class

Public Class RandomNumbersXmlReader
    Inherits XmlDictionaryReader
    'code to serve up 100000 random numbers in XML form omitted

Hasonlóképpen érdemes lehet felülbírálni OnCreateBufferedCopy a saját MessageBuffer származtatott osztály visszaadásához.

Az üzenettörzs tartalmának megadása mellett az üzenet származtatott osztályának felül kell bírálnia a , Headersés Properties a Versiontulajdonságokat is.

Vegye figyelembe, hogy ha másolatot készít egy üzenetről, a másolat az eredeti üzenetfejléceket használja.

Egyéb felülírható tagok

Felülbírálhatja a OnWriteStartEnvelopeSOAP-borítékOnWriteStartHeadersOnWriteStartBody, a SOAP-fejlécek és a SOAP törzselem kezdőcímkék írásának módját. Ezek általában a következőknek felelnek meg<soap:Envelope>: , <soap:Header>és <soap:Body>. Ezek a metódusok általában nem írnak ki semmit, ha a Version tulajdonság visszatér None.

Feljegyzés

A hívások OnWriteStartEnvelope alapértelmezett implementációja, az OnWriteStartBody eredmények meghívása OnGetReaderAtBodyContents OnWriteBodyContents és pufferelése előtt. A fejlécek nincsenek kiírva.

Felülbírálhatja a OnWriteMessage metódust a teljes üzenet különböző részeiből való felépítésének módosításához. A OnWriteMessage metódus meghívása az alapértelmezett OnCreateBufferedCopy implementációból történikWriteMessage. Vegye figyelembe, hogy a felülírás WriteMessage nem ajánlott eljárás. Jobb, ha felülbírálja a megfelelő On metódusokat (például OnWriteStartEnvelope, OnWriteStartHeadersés OnWriteBodyContents.

Felülbírálás az üzenettörzs hibakeresés közbeni ábrázolási módjának felülbírálásához OnBodyToString . Az alapértelmezett érték az, hogy három pontként ("...") jeleníti meg. Vegye figyelembe, hogy ezt a metódust többször is meghívhatja, ha az üzenet állapota nem zárt. Ennek a módszernek a megvalósítása soha nem okozhat olyan műveletet, amelyet csak egyszer kell végrehajtani (például csak továbbítási adatfolyamból történő olvasást).

Bírálja felül a metódust OnGetBodyAttribute , hogy engedélyezze az attribútumokhoz való hozzáférést a SOAP törzselemen. Ez a metódus tetszőleges számú alkalommal hívható meg, de az Message alaptípus garantálja, hogy csak akkor hívják meg, ha az üzenet Létrehozás állapotban van. Nem szükséges ellenőrizni az állapotot egy implementációban. Az alapértelmezett implementáció mindig visszaadja nullaz értéket, ami azt jelzi, hogy nincsenek attribútumok a törzselemen.

Ha az Message objektumnak speciális tisztítást kell végeznie, ha már nincs szükség az üzenettörzsre, felülbírálhatja a parancsot OnClose. Az alapértelmezett implementáció nem végez semmit.

A IsEmpty tulajdonságok felülírhatók IsFault . Alapértelmezés szerint mindkettő ad vissza false.