İ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
veyaref
parametresi olamaz.Birden
input
fazla parametre olamaz. Parametre varsa, İleti veya ileti sözleşme türü olmalıdır.Dönüş türü ,
Message
veya 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 OperationContext Current 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 XmlReader XmlDictionaryReader 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 XmlDictionaryReader XmlReader 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 MessageFault
MessageFault.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 GetReaderAtBodyContents
ve 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 IXPathNavigable MessageBuffer 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 MessageBuffer
ile ç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 Message
adları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 DataContractSerializer
kullanmak istiyorsanız, kullanan aşırı yüklemelerden XmlObjectSerializer
birini 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 GetHeader
birleşimidirFindHeader
.
Özelliklerle Çalışma
Bir Message
örnek, rastgele türlerde rastgele sayıda adlandırılmış nesne içerebilir. Bu koleksiyona türündeki Properties
MessageProperties
özelliği aracılığıyla erişilir. Koleksiyon arabirimini IDictionary<TKey,TValue> uygular ve ile String Objecteş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 , Headers
ve Properties
özelliklerini de geçersiz kılması Version
gerekir.
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 Version Nonebu 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
.