Aracılığıyla paylaş


İleti Sınıfını Kullanma

sınıfı Message , Windows Communication Foundation (WCF) için temeldir. İstemciler ve hizmetler arasındaki tüm iletişim sonunda örneklerin Message gönderilmesine ve alınmasına neden olur.

Genellikle doğrudan sınıfla etkileşim kurmazsınız Message . Bunun yerine, gelen ve giden iletileri açıklamak için veri sözleşmeleri, ileti sözleşmeleri ve işlem sözleşmeleri gibi WCF hizmet modeli yapıları kullanılır. Ancak, bazı gelişmiş senaryolarda sınıfını doğrudan kullanarak Message programlayabilirsiniz. Örneğin, sınıfını Message kullanmak isteyebilirsiniz:

  • .NET Framework nesnelerini seri hale getirme yerine giden ileti içeriğini (örneğin, doğrudan disk üzerindeki bir dosyadan ileti oluşturma) oluşturmanın alternatif bir yoluna ihtiyacınız olduğunda.

  • .NET Framework nesnelerine seri durumdan çıkarma yerine gelen ileti içeriğini kullanmanın alternatif bir yoluna ihtiyacınız olduğunda (örneğin, ham XML içeriğine XSLT dönüşümü uygulamak istediğinizde).

  • İleti içeriğinden bağımsız olarak iletilerle genel bir şekilde ilgilenmeniz gerektiğinde (örneğin, yönlendirici, yük dengeleyici veya yayımla-abone olma sistemi oluştururken iletileri yönlendirme veya iletme).

sınıfını Message kullanmadan önce, Veri Aktarımı Mimarisine Genel Bakış'ta WCF veri aktarımı mimarisi hakkında bilgi edinin.

A Message , veriler için genel amaçlı bir kapsayıcıdır, ancak tasarımı SOAP protokolündeki bir iletinin tasarımını yakından izler. SOAP'de olduğu gibi, iletinin hem ileti gövdesi hem de üst bilgileri vardır. İleti gövdesi gerçek yük verilerini içerirken üst bilgiler başka adlandırılmış veri kapsayıcıları içerir. Gövdeyi ve üst bilgileri okuma ve yazma kuralları farklıdır; örneğin, üst bilgiler her zaman bellekte arabelleğe alınabilir ve gövde yalnızca bir kez okunabilir ve akışla aktarılabilirken, istediğiniz sayıda sırayla erişilebilir. Normalde, SOAP kullanılırken ileti gövdesi SOAP gövdesine ve ileti üst bilgileri SOAP üst bilgilerine eşlenir.

İşlemlerde İleti Sınıfını Kullanma

sınıfını Message bir işlemin giriş parametresi, işlemin dönüş değeri veya her ikisi olarak kullanabilirsiniz. Bir işlemin herhangi bir yerinde kullanılırsa Message aşağıdaki kısıtlamalar geçerlidir:

  • İşlemin herhangi bir out veya ref parametresi olamaz.

  • Birden input fazla parametre olamaz. Parametre varsa, İleti veya ileti sözleşme türü olmalıdır.

  • Dönüş türü , Messageveya ileti sözleşmesi türünde olmalıdırvoid.

Aşağıdaki kod örneği geçerli bir işlem sözleşmesi içerir.

[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

Temel İletiler Oluşturma

sınıfı, Message temel iletiler oluşturmak için kullanabileceğiniz statik CreateMessage fabrika yöntemleri sağlar.

Tüm CreateMessage aşırı yüklemeler, ileti için kullanılacak SOAP ve WS-Addressing sürümlerini gösteren türde MessageVersion bir sürüm parametresi alır. Gelen iletiyle aynı protokol sürümlerini kullanmak istiyorsanız, özelliğinden OperationContextCurrent alınan örnekte özelliğini kullanabilirsinizIncomingMessageVersion. Çoğu CreateMessage aşırı yükleme, ileti için kullanılacak SOAP eylemini gösteren bir dize parametresine de sahiptir. Soap zarfı oluşturmayı devre dışı bırakmak için None sürüm olarak ayarlanabilir; ileti yalnızca gövdeden oluşur.

Nesnelerden İleti Oluşturma

Yalnızca bir sürümü alan en temel CreateMessage aşırı yükleme ve eylem boş gövdeli bir ileti oluşturur. Başka bir aşırı yükleme ek Object bir parametre alır; bu, gövdesi verilen nesnenin serileştirilmiş gösterimi olan bir ileti oluşturur. DataContractSerializer Serileştirme için varsayılan ayarlarla seçeneğini kullanın. Farklı bir seri hale getirici kullanmak veya farklı şekilde yapılandırılmasını DataContractSerializer istiyorsanız, parametreyi de alan XmlObjectSerializer aşırı yüklemeyi kullanınCreateMessage.

Örneğin, iletideki bir nesneyi döndürmek için aşağıdaki kodu kullanabilirsiniz.

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

XML Okuyucularından İleti Oluşturma

Nesne yerine gövde için veya XmlReaderXmlDictionaryReader alan aşırı yüklemeler CreateMessage vardır. Bu durumda iletinin gövdesi, geçirilen XML okuyucusundan okunan XML'yi içerir. Örneğin, aşağıdaki kod bir XML dosyasından okunan gövde içeriğini içeren bir ileti döndürür.

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

Ayrıca, yalnızca gövdeyi değil iletinin tamamını temsil eden veya XmlDictionaryReaderXmlReader alan aşırı yüklemeler vardırCreateMessage. Bu aşırı yüklemeler bir tamsayı maxSizeOfHeaders parametresi de alır. İleti oluşturulur oluşturulmaz üst bilgiler her zaman belleğe arabelleğe alınır ve bu parametre gerçekleşen arabelleğe alma miktarını sınırlar. Hizmet reddi saldırısı olasılığını azaltmak için XML güvenilmeyen bir kaynaktan geliyorsa, bu parametreyi güvenli bir değere ayarlamak önemlidir. XML okuyucunun temsil ettiği iletinin SOAP ve WS-Adresleme sürümleri, sürüm parametresi kullanılarak belirtilen sürümlerle eşleşmelidir.

BodyWriter ile İleti Oluşturma

Bir CreateMessage aşırı yükleme, iletinin gövdesini açıklamak için bir BodyWriter örnek alır. a BodyWriter , ileti gövdelerinin oluşturulma biçimini özelleştirmek için türetilebilen soyut bir sınıftır. İleti gövdelerini özel bir şekilde açıklamak için kendi BodyWriter türetilmiş sınıfınızı oluşturabilirsiniz. Bir alan XmlDictionaryWriteryöntemini geçersiz kılmanız BodyWriter.OnWriteBodyContents gerekir; bu yöntem gövdeyi yazmaktan sorumludur.

Gövde yazarları arabelleğe alınabiliyor veya arabelleğe alınamıyor (akışa alınabiliyor). Arabelleğe alınan gövde yazarları içeriklerini istedikleri sayıda yazabilirken, akışlı olanlar içeriklerini yalnızca bir kez yazabilir. IsBuffered özelliği, bir gövde yazıcısının arabelleğe alınıp alınmadığını gösterir. Boole parametresini alan isBuffered korumalı BodyWriter oluşturucuyu çağırarak bunu gövde yazıcınız için ayarlayabilirsiniz. Gövde yazarları, arabelleğe alınamayan bir gövde yazıcısından arabelleğe alınan bir gövde yazıcısı oluşturmayı destekler. Bu işlemi özelleştirmek OnCreateBufferedCopy için yöntemini geçersiz kılabilirsiniz. Varsayılan olarak, tarafından OnWriteBodyContents döndürülen XML'yi içeren bir bellek içi arabellek kullanılır. OnCreateBufferedCopy bir maxBufferSize tamsayı parametresi alır; bu yöntemi geçersiz kılarsanız, bu en büyük boyuttan daha büyük arabellekler oluşturmamalısınız.

BodyWriter sınıfı, temelde sırasıyla ve CreateBufferedCopy yöntemleri etrafında OnWriteBodyContents ince sarmalayıcılar olan ve OnCreateBufferedCopy yöntemlerini sağlarWriteBodyContents. Bu yöntemler, arabelleğe alınmayan bir gövde yazıcısına birden çok kez erişilmediğinden emin olmak için durum denetimi gerçekleştirir. Bu yöntemler yalnızca tabanlı BodyWritersözel Message türetilmiş sınıflar oluştururken doğrudan çağrılır.

Hata İletileri Oluşturma

SOAP hata iletileri oluşturmak için bazı CreateMessage aşırı yüklemeleri kullanabilirsiniz. Bunların en temeli, hatayı tanımlayan bir MessageFault nesne alır. Kolaylık sağlamak için diğer aşırı yüklemeler sağlanır. Bu tür ilk aşırı yükleme bir FaultCode ve neden dizesi alır ve bu bilgileri kullanarak bir MessageFaultMessageFault.CreateFault oluşturur. Diğer aşırı yükleme bir ayrıntı nesnesi alır ve hata CreateFault kodu ve nedeni ile birlikte geçirir. Örneğin, aşağıdaki işlem bir hata döndürür.

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

İleti Gövdesi Verilerini Ayıklama

sınıfı, Message gövdesinden bilgi ayıklamanın birden çok yolunu destekler. Bunlar aşağıdaki kategorilere sınıflandırılabilir:

  • bir XML yazıcısına ileti gövdesinin tamamını aynı anda yazma. Bu, ileti yazma olarak adlandırılır.

  • İleti gövdesi üzerinde XML okuyucu alma. Bu, daha sonra ileti gövdesine gerektiği gibi parça parça erişmenizi sağlar. Bu, ileti okuma olarak adlandırılır.

  • Gövdesi de dahil olmak üzere iletinin tamamı, türünde bir bellek içi arabelleğe MessageBuffer kopyalanabilir. Bu, ileti kopyalama olarak adlandırılır.

Gövdesine nasıl erişildiğinden bağımsız olarak yalnızca bir Message kez erişebilirsiniz. İleti nesnesinin başlangıçta Oluşturuldu olarak ayarlanmış bir State özelliği vardır. Önceki listede açıklanan üç erişim yöntemi, durumu sırasıyla Yazılı, Okundu ve Kopyalandı olarak ayarlar. Ayrıca, ileti gövdesi içeriği artık gerekli olmadığında bir Close yöntem durumu Kapalı olarak ayarlayabilir. İleti gövdesine yalnızca Oluşturuldu durumunda erişilebilir ve durum değiştikten sonra Oluşturuldu durumuna geri dönmenin hiçbir yolu yoktur.

İleti Yazma

yöntemi, WriteBodyContents(XmlDictionaryWriter) belirli bir örneğin gövde içeriğini belirli Message bir XML yazıcısına yazar. WriteBody yöntemi, gövde içeriğini uygun sarmalayıcı öğesine (örneğin, <soap:body>) kapatması dışında aynı işlemi yapar. Son olarak, WriteMessage sarmalama SOAP zarfı ve üst bilgiler de dahil olmak üzere iletinin tamamını yazar. SOAP kapalıysa (Version is MessageVersion.None), üç yöntem de aynı şeyi yapar: ileti gövdesi içeriğini yazar.

Örneğin, aşağıdaki kod bir dosyaya gelen iletinin gövdesini yazar.

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

İki ek yardımcı yöntem, belirli SOAP başlangıç öğesi etiketlerini yazar. Bu yöntemler ileti gövdesine erişmez ve bu nedenle ileti durumunu değiştirmez. Bu modüller şunlardır:

  • WriteStartBody başlangıç gövdesi öğesini yazar, örneğin, <soap:Body>.

  • WriteStartEnvelope başlangıç zarfı öğesini yazar, örneğin, <soap:Envelope>.

İlgili son öğe etiketlerini yazmak için ilgili XML yazıcısını çağırın WriteEndElement . Bu yöntemler nadiren doğrudan çağrılır.

İletileri Okuma

İleti gövdesini okumanın birincil yolu çağrısı GetReaderAtBodyContentsyapmaktır. İleti gövdesini okumak için kullanabileceğiniz bir XmlDictionaryReader geri alırsınız. Döndürülen XML okuyucuyu Message kullandığınızda değil, çağrıldığı anda GetReaderAtBodyContents Okuma durumuna geçişler olduğunu unutmayın.

yöntemi, GetBody ileti gövdesine yazılan bir nesne olarak erişmenizi de sağlar. Dahili olarak, bu yöntem kullanır GetReaderAtBodyContentsve bu nedenle ileti durumunu Read duruma da geçirmektedir (özelliğine State bakın).

özelliğini denetlemek IsEmpty iyi bir uygulamadır; bu durumda ileti gövdesi boş olur ve GetReaderAtBodyContents bir InvalidOperationExceptionoluşturur. Ayrıca, alınan bir iletiyse (örneğin, yanıt), iletinin bir hata içerip içermediğini gösteren öğesini de denetlemek IsFaultisteyebilirsiniz.

öğesinin GetBody en temel aşırı yüklemesi, varsayılan ayarlarla yapılandırılmış ve kota devre dışı olan bir kullanarak DataContractSerializer ileti gövdesini bir tür örneğine (genel parametreyle gösterilir) seri durumdan MaxItemsInObjectGraph çıkartır. Farklı bir serileştirme altyapısı kullanmak veya öğesini varsayılan olmayan bir şekilde yapılandırmak DataContractSerializer istiyorsanız, kullanan aşırı yüklemeyi XmlObjectSerializerkullanınGetBody.

Örneğin, aşağıdaki kod, serileştirilmiş Person bir nesne içeren bir ileti gövdesinden verileri ayıklar ve kişinin adını yazdırır.

    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

İletiyi Arabelleğe Kopyalama

Bazen, aynı iletiyi yayımcı-abone sisteminin bir parçası olarak birden çok hedefe iletmek için ileti gövdesine birden çok kez erişmek gerekir. Bu durumda, iletinin tamamının (gövde dahil) bellekte arabelleğe alınması gerekir. Bunu çağrısı CreateBufferedCopy(Int32)yaparak yapabilirsiniz. Bu yöntem, en büyük arabellek boyutunu temsil eden bir tamsayı parametresi alır ve bu boyuttan büyük olmayan bir arabellek oluşturur. İleti güvenilmeyen bir kaynaktan geliyorsa bunu güvenli bir değere ayarlamak önemlidir.

Arabellek bir MessageBuffer örnek olarak döndürülür. Arabellekteki verilere çeşitli yollarla erişebilirsiniz. Birincil yol, arabellekten örnek oluşturmak Message için çağrısı CreateMessage yapmaktır.

Arabellekteki verilere erişmenin bir diğer yolu da sınıfın IXPathNavigableMessageBuffer temel XML'ye doğrudan erişmek için uyguladığı arabirimi uygulamaktır. Bazı CreateNavigator aşırı yüklemeler, ziyaret edilebilecek XML düğümlerinin sayısını sınırlayarak düğüm kotası ile korunan gezgin oluşturmanıza System.Xml.XPath olanak sağlar. Bu, uzun işleme süresine göre hizmet reddi saldırılarını önlemeye yardımcı olur. Bu teklif varsayılan olarak devre dışıdır. Bazı CreateNavigator aşırı yüklemeler, sabit listesi kullanılarak XmlSpace XML'de boş alanın nasıl işleneceğini belirtmenize olanak sağlar ve varsayılan değer olur XmlSpace.None.

İleti arabelleğinin içeriğine erişmenin son yolu, kullanarak içeriğini bir akışa WriteMessageyazmaktır.

Aşağıdaki örnekte, bir MessageBufferile çalışma işlemi gösterilmektedir: gelen ileti birden çok alıcıya iletilir ve sonra bir dosyaya kaydedilir. Arabelleğe alma olmadan, ileti gövdesine yalnızca bir kez erişilebildiği için bu mümkün değildir.

[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

Sınıfın MessageBuffer dikkate değer başka üyeleri vardır. Close Arabellek içeriği artık gerekli olmadığında kaynakları boşaltmak için yöntemi çağrılabilir. BufferSize özelliği, ayrılan arabelleğin boyutunu döndürür. özelliği, MessageContentType iletinin MIME içerik türünü döndürür.

Hata Ayıklama için İleti Gövdesine Erişme

Hata ayıklama amacıyla, iletinin ToString dize olarak bir gösterimini almak için yöntemini çağırabilirsiniz. Bu gösterim genellikle iletinin metin kodlayıcıyla kodlanmış olması durumunda iletinin kabloda nasıl görüneceğiyle eşleşir, ancak XML insan okunabilirliği için daha iyi biçimlendirilir. Bunun tek istisnası ileti gövdesidir. Gövde yalnızca bir kez okunabilir ve ToString ileti durumunu değiştirmez. Bu nedenle, ToString yöntem gövdeye erişemeyebilir ve bir yer tutucu (örneğin, "..." veya üç nokta) yerine ileti gövdesini seçin. Bu nedenle, iletilerin gövde içeriği önemliyse iletileri günlüğe kaydetmek için kullanmayın ToString .

Diğer İleti Bölümlerine Erişme

İleti hakkında gövde içeriği dışındaki bilgilere erişmek için çeşitli özellikler sağlanır. Ancak, ileti kapatıldıktan sonra bunlar çağrılamaz:

  • Headers özelliği ileti üst bilgilerini temsil eder. Bu konunun devamında yer alan "Üst Bilgilerle Çalışma" bölümüne bakın.

  • Properties özelliği, ileti gönderildiğinde genellikle gönderilmeyen iletiye eklenmiş adlandırılmış veri parçaları olan ileti özelliklerini temsil eder. Bu konunun devamında yer alan "Özelliklerle Çalışma" bölümüne bakın.

  • Version özelliği, iletiyle ilişkili SOAP ve WS-Addressing sürümünü veya None SOAP'nin devre dışı bırakılıp bırakılmadiğini gösterir.

  • özelliği, IsFault ileti bir SOAP hata iletisiyse döndürür true .

  • özelliği, IsEmpty ileti boşsa döndürür true .

yöntemini kullanarak GetBodyAttribute(String, String) , belirli bir ad ve ad alanı tarafından tanımlanan gövde sarmalayıcı öğesindeki (örneğin, <soap:Body>) belirli bir özniteliğe erişebilirsiniz. Böyle bir öznitelik bulunmazsa döndürülür null . Bu yöntem yalnızca oluşturuldu durumunda olduğunda Message (ileti gövdesine henüz erişilmediğinde) çağrılabilir.

Üst Bilgilerle Çalışma

AMessage, üst bilgi olarak adlandırılan herhangi bir sayıda adlandırılmış XML parçası içerebilir. Her parça normalde bir SOAP üst bilgisine eşler. Üst bilgiler türündeki Headers özelliği MessageHeadersaracılığıyla erişilir. MessageHeaders bir nesne koleksiyonudur MessageHeaderInfo ve tek tek üst bilgiler arabirimi veya IEnumerable dizin oluşturucu aracılığıyla erişilebilir. Örneğin, aşağıdaki kod içindeki tüm üst bilgilerin Messageadlarını listeler.

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

Üst Bilgileri Ekleme, Kaldırma, Bulma

yöntemini kullanarak Add var olan tüm üst bilgilerin sonuna yeni bir üst bilgi ekleyebilirsiniz. Yöntemini kullanarak Insert belirli bir dizine üst bilgi ekleyebilirsiniz. Eklenen öğe için varolan üst bilgiler kaydırılır. Üst bilgiler dizinlerine göre sıralanır ve kullanılabilir ilk dizin 0'dır. Farklı Message bir veya MessageHeaders örnekten üst bilgi eklemek için çeşitli CopyHeadersFrom yöntem aşırı yüklemelerini kullanabilirsiniz. Bazı aşırı yüklemeler tek bir üst bilgiyi kopyalarken, diğerleri bunların tümünü kopyalar. Clear yöntemi tüm üst bilgileri kaldırır. yöntemi, RemoveAt belirli bir dizindeki üst bilgiyi kaldırır (bundan sonraki tüm üst bilgileri kaydırarak). yöntemi, RemoveAll belirli bir ada ve ad alanına sahip tüm üst bilgileri kaldırır.

yöntemini kullanarak FindHeader belirli bir üst bilgiyi alın. Bu yöntem, bulmak için üst bilginin adını ve ad alanını alır ve dizinini döndürür. Üst bilgi birden çok kez oluşursa, bir özel durum oluşturulur. Üst bilgi bulunmazsa -1 döndürür.

SOAP üst bilgi modelinde üst bilgiler, üst bilginin hedeflenen alıcısını belirten bir Actor değere sahip olabilir. En temel FindHeader aşırı yükleme yalnızca iletinin nihai alıcısı için amaçlanan üst bilgileri arar. Ancak başka bir aşırı yükleme, aramaya hangi Actor değerlerin dahil olduğunu belirtmenizi sağlar. Daha fazla bilgi için bkz. SOAP belirtimi.

Üst CopyTo(MessageHeaderInfo[], Int32) bilgileri bir koleksiyondan bir MessageHeaders nesne dizisine MessageHeaderInfo kopyalamak için bir yöntem sağlanır.

Üst bilgideki XML verilerine erişmek için, belirli bir üst bilgi dizini için bir XML okuyucu çağırabilir GetReaderAtHeader ve döndürebilirsiniz. Üst bilgi içeriğini bir nesnede seri durumdan çıkarmak istiyorsanız veya diğer aşırı yüklemelerden birini kullanın GetHeader<T>(Int32) . En temel aşırı yüklemeler, varsayılan şekilde yapılandırılan öğesini DataContractSerializer kullanarak üst bilgileri seri durumdan çıkartır. farklı bir seri hale getirici veya farklı bir yapılandırma DataContractSerializerkullanmak istiyorsanız, kullanan aşırı yüklemelerden XmlObjectSerializerbirini kullanın. Üst bilgi adını, ad alanını ve isteğe bağlı olarak dizin yerine değerlerin Actor listesini alan aşırı yüklemeler de vardır; bu, ve GetHeaderbirleşimidirFindHeader.

Özelliklerle Çalışma

Bir Message örnek, rastgele türlerde rastgele sayıda adlandırılmış nesne içerebilir. Bu koleksiyona türündeki PropertiesMessagePropertiesözelliği aracılığıyla erişilir. Koleksiyon arabirimini IDictionary<TKey,TValue> uygular ve ile StringObjecteşlemesi olarak davranır. Normalde, özellik değerleri iletinin kablodaki herhangi bir bölümüne doğrudan eşlenmez, bunun yerine WCF kanal yığınındaki çeşitli kanallara veya hizmet çerçevesine CopyTo(MessageHeaderInfo[], Int32) çeşitli ileti işleme ipuçları sağlar. Örnek için bkz . Veri Aktarımı Mimarisine Genel Bakış.

İleti Sınıfından Devralma

kullanılarak CreateMessage oluşturulan yerleşik ileti türleri gereksinimlerinizi karşılamıyorsa, sınıfından Message türetilen bir sınıf oluşturun.

İleti Gövdesi İçeriğini Tanımlama

İleti gövdesindeki verilere erişmek için üç temel teknik vardır: yazma, okuma ve bir arabelleğe kopyalama. Bu işlemler sonuçta OnWriteBodyContentsOnGetReaderAtBodyContentstüretilmiş sınıfınızda sırasıyla , ve OnCreateBufferedCopy yöntemlerinin çağrılmasını sağlarMessage. Temel Message sınıf, her Message örnek için bu yöntemlerden yalnızca birinin çağrıldığını ve birden çok kez çağrılmadığını garanti eder. Temel sınıf ayrıca yöntemlerin kapalı bir iletide çağrılmamasını sağlar. Uygulamanızda ileti durumunu izlemenize gerek yoktur.

OnWriteBodyContents soyut bir yöntemdir ve uygulanması gerekir. İletinizin gövde içeriğini tanımlamanın en temel yolu, bu yöntemi kullanarak yazmaktır. Örneğin, aşağıdaki ileti 1 ile 20 arasını içeren 100.000 rastgele sayı içerir.

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.

OnGetReaderAtBodyContents() ve OnCreateBufferedCopy yöntemleri, çoğu durumda çalışan varsayılan uygulamalara sahiptir. Varsayılan uygulamalar öğesini çağırır OnWriteBodyContents, sonuçları arabelleğe alır ve sonuçta elde edilen arabellekle çalışır. Ancak, bazı durumlarda bu yeterli olmayabilir. Yukarıdaki örnekte, iletinin okunması 100.000 XML öğesinin arabelleğe alınmasıyla sonuçlanır ve bu istenmeyebilir. Rastgele sayılara hizmet eden özel XmlDictionaryReader türetilmiş bir sınıf döndürmek için geçersiz kılmak OnGetReaderAtBodyContents() isteyebilirsiniz. Ardından, aşağıdaki örnekte gösterildiği gibi yöntemin döndürdüğü okuyucuyu OnGetReaderAtBodyContents() kullanmak için geçersiz kılabilirsinizOnWriteBodyContents.

    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

Benzer şekilde, kendi MessageBuffer türetilmiş sınıfınızı döndürmek için geçersiz kılmak OnCreateBufferedCopy isteyebilirsiniz.

İleti gövdesi içeriği sağlamanın yanı sıra, ileti türetilmiş sınıfınızın , Headersve Properties özelliklerini de geçersiz kılması Versiongerekir.

bir iletinin kopyasını oluşturursanız, kopyanın özgün ileti üst bilgilerini kullandığını unutmayın.

Geçersiz Kılınabilecek Diğer Üyeler

SOAP zarfıOnWriteStartEnvelopeOnWriteStartHeaders, SOAP üst bilgileri ve OnWriteStartBody SOAP gövde öğesi başlangıç etiketlerinin nasıl yazılacağını belirtmek için , ve yöntemlerini geçersiz kılabilirsiniz. Bunlar normalde , <soap:Header>ve <soap:Body>değerlerine <soap:Envelope>karşılık gelir. Özelliği döndürürse VersionNonebu yöntemler normalde hiçbir şey yazmamalıdır.

Not

Çağrıların OnGetReaderAtBodyContents varsayılan uygulaması ve OnWriteStartBody sonuçları OnWriteStartEnvelope çağırmadan OnWriteBodyContents ve arabelleğe almadan önce. Üst bilgiler yazılmaz.

tüm iletinin OnWriteMessage çeşitli parçalarından oluşturma şeklini değiştirmek için yöntemini geçersiz kılın. OnWriteMessage yöntemi, varsayılan OnCreateBufferedCopy uygulamadan WriteMessage ve uygulamasından çağrılır. Geçersiz kılmanın WriteMessage en iyi yöntem olmadığını unutmayın. Uygun On yöntemleri (örneğin, OnWriteStartEnvelope, OnWriteStartHeadersve OnWriteBodyContents) geçersiz kılmak daha iyidir.

Hata ayıklama sırasında ileti gövdesinin nasıl temsil edilir geçersiz kılmak için geçersiz kılın OnBodyToString . Varsayılan değer, bunu üç nokta ("...") olarak göstermektir. İleti durumu Kapalı dışında bir şey olduğunda bu yöntemin birden çok kez çağrılabileceğini unutmayın. Bu yöntemin uygulanması hiçbir zaman yalnızca bir kez gerçekleştirilmesi gereken herhangi bir eyleme neden olmamalıdır (örneğin, yalnızca iletme akışından okuma).

SOAP gövde öğesindeki OnGetBodyAttribute özniteliklere erişime izin vermek için yöntemini geçersiz kılın. Bu yöntem herhangi bir sayıda çağrılabilir, ancak Message temel türü yalnızca ileti Oluşturuldu durumunda olduğunda çağrılabileceğini garanti eder. Bir uygulamadaki durumu denetlemek gerekli değildir. Varsayılan uygulama her zaman döndürür null. Bu, gövde öğesinde öznitelik olmadığını gösterir.

İleti gövdesi artık gerekli olmadığında nesnenizin Message herhangi bir özel temizleme yapması gerekiyorsa, öğesini geçersiz kılabilirsiniz OnClose. Varsayılan uygulama hiçbir şey yapmaz.

IsEmpty ve IsFault özellikleri geçersiz kılınabilir. Varsayılan olarak, her ikisi de döndürür false.