Hizmet Sözleşmelerinde Veri Aktarımını Belirtme
Windows Communication Foundation (WCF) bir mesajlaşma altyapısı olarak düşünülebilir. Hizmet işlemleri iletileri alabilir, işleyebilir ve ileti gönderebilir. İletiler, işlem sözleşmeleri kullanılarak açıklanır. Örneğin, aşağıdaki sözleşmeyi göz önünde bulundurun.
[ServiceContract]
public interface IAirfareQuoteService
{
[OperationContract]
float GetAirfare(string fromCity, string toCity);
}
<ServiceContract()>
Public Interface IAirfareQuoteService
<OperationContract()>
Function GetAirfare(fromCity As String, toCity As String) As Double
End Interface
Burada, GetAirfare
işlem ve toCity
hakkında fromCity
bilgi içeren bir iletiyi kabul eder ve ardından sayı içeren bir ileti döndürür.
Bu konu başlığı altında, bir işlem sözleşmesinin iletileri açıklayabilmesinin çeşitli yolları açıklanmaktadır.
Parametreleri Kullanarak İletileri Açıklama
İletiyi açıklamanın en basit yolu parametre listesini ve dönüş değerini kullanmaktır. Yukarıdaki örnekte, fromCity
istek iletisini açıklamak için ve toCity
dize parametreleri kullanılmış ve yanıt iletisini açıklamak için float dönüş değeri kullanılmıştır. Yalnızca dönüş değeri yanıt iletisini açıklamak için yeterli değilse out parametreleri kullanılabilir. Örneğin, aşağıdaki işlemin istek iletisinde ve toCity
yanıt iletisinde para birimiyle birlikte bir sayı vardırfromCity
:
[OperationContract]
float GetAirfare(string fromCity, string toCity, out string currency);
<OperationContract()>
Function GetAirfare(fromCity As String, toCity As String) As Double
Ayrıca, hem isteğin hem de yanıt iletisinin bir parametresini yapmak için başvuru parametrelerini kullanabilirsiniz. Parametreler seri hale getirilebilen (XML'ye dönüştürülebilen) türlerde olmalıdır. WcF, bu dönüştürmeyi DataContractSerializer gerçekleştirmek için varsayılan olarak sınıfı adlı bir bileşeni kullanır. Çoğu ilkel tür (, , float
ve DateTime
. gibiint
string
) desteklenir. Kullanıcı tanımlı türlerin normalde bir veri sözleşmesi olmalıdır. Daha fazla bilgi için bkz . Veri Sözleşmelerini Kullanma.
public interface IAirfareQuoteService
{
[OperationContract]
float GetAirfare(Itinerary itinerary, DateTime date);
[DataContract]
public class Itinerary
{
[DataMember]
public string fromCity;
[DataMember]
public string toCity;
}
}
Public Interface IAirfareQuoteService
<OperationContract()>
GetAirfare(itinerary as Itinerary, date as DateTime) as Double
<DataContract()>
Class Itinerary
<DataMember()>
Public fromCity As String
<DataMember()>
Public toCity As String
End Class
End Interface
Bazen, DataContractSerializer
türlerinizi seri hale getirmek için yeterli değildir. WCF, XmlSerializerparametreleri seri hale getirmek için de kullanabileceğiniz alternatif bir serileştirme altyapısını destekler. gibi XmlSerializer öznitelikleri kullanarak sonuçta elde edilen XML üzerinde daha fazla denetim kullanmanıza XmlAttributeAttribute
olanak tanır. öğesini belirli bir işlemde veya hizmetin tamamında kullanmaya XmlSerializer geçmek için özniteliğini XmlSerializerFormatAttribute bir işleme veya hizmete uygulayın. Örneğin:
[ServiceContract]
public interface IAirfareQuoteService
{
[OperationContract]
[XmlSerializerFormat]
float GetAirfare(Itinerary itinerary, DateTime date);
}
public class Itinerary
{
public string fromCity;
public string toCity;
[XmlAttribute]
public bool isFirstClass;
}
<ServiceContract()>
Public Interface IAirfareQuoteService
<OperationContract()>
<XmlSerializerFormat>
GetAirfare(itinerary as Itinerary, date as DateTime) as Double
End Interface
Class Itinerary
Public fromCity As String
Public toCity As String
<XmlSerializerFormat()>
Public isFirstClass As Boolean
End Class
Daha fazla bilgi için bkz . XmlSerializer Sınıfını Kullanma. Burada gösterildiği gibi el ile konumuna geçmenin XmlSerializer , bu konuda ayrıntılı olarak açıklandığı gibi belirli nedenleriniz olmadığı sürece önerilmediğini unutmayın.
.NET parametre adlarını sözleşme adlarından yalıtmak için özniteliğini MessageParameterAttribute ve özelliğini kullanarak sözleşme adını ayarlayabilirsiniz Name
. Örneğin, aşağıdaki işlem sözleşmesi bu konudaki ilk örnekle eşdeğerdir.
[OperationContract]
public float GetAirfare(
[MessageParameter(Name="fromCity")] string originCity,
[MessageParameter(Name="toCity")] string destinationCity);
<OperationContract()>
Function GetAirfare(<MessageParameter(Name := "fromCity")> fromCity As String, <MessageParameter(Name := "toCity")> toCity As String) As Double
Boş İletileri Açıklama
Boş bir istek iletisi, giriş veya başvuru parametresi olmadan açıklanabilir. Örneğin, C# içinde:
[OperationContract]
public int GetCurrentTemperature();
Örneğin, Visual Basic'te:
<OperationContract()>
Function GetCurrentTemperature() as Integer
Boş bir yanıt iletisi, bir dönüş türüne sahip void
olup çıkış veya başvuru parametresi olmadan açıklanabilir. Örneğin:
[OperationContract]
public void SetTemperature(int temperature);
<OperationContract()>
Sub SetTemperature(temperature As Integer)
Bu, aşağıdakiler gibi tek yönlü bir işlemden farklıdır:
[OperationContract(IsOneWay=true)]
public void SetLightbulbStatus(bool isOn);
<OperationContract(IsOneWay:=True)>
Sub SetLightbulbStatus(isOne As Boolean)
İşlem SetTemperatureStatus
boş bir ileti döndürür. Bunun yerine, giriş iletisini işlerken bir sorun varsa hata döndürebilir. İşlem SetLightbulbStatus
hiçbir şey döndürmez. Bu işlemden hata durumunu iletmenin hiçbir yolu yoktur.
İleti Sözleşmelerini Kullanarak İletileri Açıklama
İletinin tamamını temsil etmek için tek bir tür kullanmak isteyebilirsiniz. Bu amaçla bir veri sözleşmesi kullanmak mümkün olsa da, bunu yapmak için önerilen yol ileti sözleşmesi kullanmaktır; bu, sonuçta elde edilen XML'de gereksiz sarmalama düzeylerini önler. Ayrıca ileti sözleşmeleri, sonuçta elde edilen iletiler üzerinde daha fazla denetim sahibi olmanıza olanak sağlar. Örneğin, hangi bilgi parçalarının ileti gövdesinde ve hangilerinin ileti üst bilgilerinde yer alması gerektiğine karar vekleyebilirsiniz. Aşağıdaki örnekte ileti sözleşmelerinin kullanımı gösterilmektedir.
[ServiceContract]
public interface IAirfareQuoteService
{
[OperationContract]
GetAirfareResponse GetAirfare(GetAirfareRequest request);
}
[MessageContract]
public class GetAirfareRequest
{
[MessageHeader] public DateTime date;
[MessageBodyMember] public Itinerary itinerary;
}
[MessageContract]
public class GetAirfareResponse
{
[MessageBodyMember] public float airfare;
[MessageBodyMember] public string currency;
}
[DataContract]
public class Itinerary
{
[DataMember] public string fromCity;
[DataMember] public string toCity;
}
<ServiceContract()>
Public Interface IAirfareQuoteService
<OperationContract()>
Function GetAirfare(request As GetAirfareRequest) As GetAirfareResponse
End Interface
<MessageContract()>
Public Class GetAirfareRequest
<MessageHeader()>
Public Property date as DateTime
<MessageBodyMember()>
Public Property itinerary As Itinerary
End Class
<MessageContract()>
Public Class GetAirfareResponse
<MessageBodyMember()>
Public Property airfare As Double
<MessageBodyMember()> Public Property currency As String
End Class
<DataContract()>
Public Class Itinerary
<DataMember()> Public Property fromCity As String
<DataMember()> Public Property toCity As String
End Class
Daha fazla bilgi için bkz . İleti Sözleşmelerini Kullanma.
Önceki örnekte sınıfı varsayılan olarak kullanılmaya DataContractSerializer devam etmektedir. sınıfı ileti XmlSerializer sözleşmeleriyle de kullanılabilir. Bunu yapmak için özniteliğini XmlSerializerFormatAttribute işleme veya sözleşmeye uygulayın ve ileti üst bilgilerinde ve gövde üyelerinde sınıfıyla XmlSerializer uyumlu türleri kullanın.
Akışlar Kullanarak İletileri Açıklama
İşlemlerdeki iletileri açıklamanın başka bir yolu, sınıfını Stream veya türetilmiş sınıflarından birini bir işlem sözleşmesinde veya ileti sözleşmesi gövde üyesi olarak kullanmaktır (bu durumda tek üye olmalıdır). Gelen iletiler için tür olmalıdır Stream
; türetilmiş sınıfları kullanamazsınız.
WCF, seri hale getiriciyi çağırmak yerine bir akıştan veri alır ve doğrudan giden iletiye yerleştirir veya gelen iletiden veri alır ve doğrudan bir akışa yerleştirir. Aşağıdaki örnekte akış kullanımı gösterilmektedir.
[OperationContract]
public Stream DownloadFile(string fileName);
<OperationContract()>
Function DownloadFile(fileName As String) As String
Tek bir ileti gövdesinde verileri birleştiremez Stream
ve akış dışı yapamazsınız. Ek verileri ileti üst bilgilerine yerleştirmek için bir ileti sözleşmesi kullanın. Aşağıdaki örnekte, işlem sözleşmesini tanımlarken akışların yanlış kullanımı gösterilmektedir.
//Incorrect:
// [OperationContract]
// public void UploadFile (string fileName, Stream fileData);
'Incorrect:
'<OperationContract()>
Public Sub UploadFile(fileName As String, fileData As StreamingContext)
Aşağıdaki örnek, bir işlem sözleşmesi tanımlarken akışların doğru kullanımını gösterir.
[OperationContract]
public void UploadFile (UploadFileMessage message);
//code omitted
[MessageContract]
public class UploadFileMessage
{
[MessageHeader] public string fileName;
[MessageBodyMember] public Stream fileData;
}
<OperationContract()>
Public Sub UploadFile(fileName As String, fileData As StreamingContext)
'Code Omitted
<MessageContract()>
Public Class UploadFileMessage
<MessageHeader()>
Public Property fileName As String
<MessageBodyMember()>
Public Property fileData As Stream
End Class
Daha fazla bilgi için bkz . Büyük Veri ve Akış.
İleti Sınıfını Kullanma
Gönderilen veya alınan iletiler üzerinde tam programlı denetime sahip olmak için, aşağıdaki örnek kodda gösterildiği gibi sınıfını doğrudan kullanabilirsiniz Message .
[OperationContract]
public void LogMessage(Message m);
<OperationContract()>
Sub LogMessage(m As Message)
Bu, İleti Sınıfını Kullanma bölümünde ayrıntılı olarak açıklanan gelişmiş bir senaryodur.
Hata İletilerini Açıklama
Dönüş değeri ve çıkış veya başvuru parametreleriyle açıklanan iletilere ek olarak, tek yönlü olmayan tüm işlemler en az iki olası ileti döndürebilir: normal yanıt iletisi ve hata iletisi. Aşağıdaki işlem sözleşmesini göz önünde bulundurun.
[OperationContract]
float GetAirfare(string fromCity, string toCity, DateTime date);
<OperationContract()>
Function GetAirfare(fromCity As String, toCity As String, date as DateTime)
Bu işlem, sayı içeren normal bir float
ileti veya hata kodu ve açıklama içeren bir hata iletisi döndürebilir. Bunu, hizmet uygulamanıza bir FaultException oluşturarak gerçekleştirebilirsiniz.
özniteliğini FaultContractAttribute kullanarak ek olası hata iletileri belirtebilirsiniz. Ek hatalar, aşağıdaki örnek kodda gösterildiği gibi kullanılarak DataContractSerializerseri hale getirilebilir olmalıdır.
[OperationContract]
[FaultContract(typeof(ItineraryNotAvailableFault))]
float GetAirfare(string fromCity, string toCity, DateTime date);
//code omitted
[DataContract]
public class ItineraryNotAvailableFault
{
[DataMember]
public bool IsAlternativeDateAvailable;
[DataMember]
public DateTime alternativeSuggestedDate;
}
<OperationContract()>
<FaultContract(GetType(ItineraryNotAvailableFault))>
Function GetAirfare(fromCity As String, toCity As String, date as DateTime) As Double
'Code Omitted
<DataContract()>
Public Class
<DataMember()>
Public Property IsAlternativeDateAvailable As Boolean
<DataMember()>
Public Property alternativeSuggestedDate As DateTime
End Class
Bu ek hatalar, uygun veri sözleşmesi türünden bir FaultException<TDetail> oluşturularak oluşturulabilir. Daha fazla bilgi için bkz . Özel Durumları ve Hataları İşleme.
Hataları açıklamak için sınıfını XmlSerializer kullanamazsınız. , XmlSerializerFormatAttribute hata sözleşmeleri üzerinde hiçbir etkiye sahip değildir.
Türetilmiş Türleri Kullanma
Bir işlemde veya ileti sözleşmesinde temel bir tür kullanmak ve ardından işlemi gerçekten çağırırken türetilmiş bir tür kullanmak isteyebilirsiniz. Bu durumda, türetilmiş türlerin kullanımına ServiceKnownTypeAttribute izin vermek için özniteliğini veya başka bir mekanizmayı kullanmanız gerekir. Aşağıdaki işlemi göz önünde bulundurun.
[OperationContract]
public bool IsLibraryItemAvailable(LibraryItem item);
<OperationContract()>
Function IsLibraryItemAvailable(item As LibraryItem) As Boolean
ve Magazine
olmak üzere iki türün Book
türünden LibraryItem
türetildiğini varsayalım. İşlemde IsLibraryItemAvailable
bu türleri kullanmak için işlemi aşağıdaki gibi değiştirebilirsiniz:
[OperationContract]
[ServiceKnownType(typeof(Book))]
[ServiceKnownType(typeof(Magazine))]
public bool IsLibraryItemAvailable(LibraryItem item);
Alternatif olarak, aşağıdaki örnek kodda gösterildiği gibi varsayılan DataContractSerializer kullanımda olduğunda özniteliğini kullanabilirsinizKnownTypeAttribute.
[OperationContract]
public bool IsLibraryItemAvailable(LibraryItem item);
// code omitted
[DataContract]
[KnownType(typeof(Book))]
[KnownType(typeof(Magazine))]
public class LibraryItem
{
//code omitted
}
<OperationContract()>
Function IsLibraryItemAvailable(item As LibraryItem) As Boolean
'Code Omitted
<DataContract()>
<KnownType(GetType(Book))>
<KnownType(GetType(Magazine))>
Public Class LibraryItem
'Code Omitted
End Class
özniteliğini XmlIncludeAttribute kullanırken XmlSerializerkullanabilirsiniz.
özniteliğini ServiceKnownTypeAttribute bir işleme veya hizmetin tamamına uygulayabilirsiniz. Özniteliği gibi KnownTypeAttribute bilinen türlerin listesini almak için çağrılacak yöntemin türünü veya adını kabul eder. Daha fazla bilgi için bkz . Veri Sözleşmesi Bilinen Türleri.
Kullanım ve Stil Belirtme
Web Hizmetleri Açıklama Dili (WSDL) kullanarak hizmetleri açıklarken, yaygın olarak kullanılan iki stil Belge ve uzak yordam çağrısıdır (RPC). Belge stilinde, ileti gövdesinin tamamı şema kullanılarak açıklanır ve WSDL çeşitli ileti gövdesi bölümlerini bu şema içindeki öğelere başvurarak açıklar. RPC stilinde, WSDL bir öğe yerine her ileti bölümü için bir şema türüne başvurur. Bazı durumlarda, bu stillerden birini el ile seçmeniz gerekir. Özniteliğini uygulayarak DataContractFormatAttribute ve özelliğini ayarlayarak Style
(kullanımda olduğundaDataContractSerializer) veya özniteliğini XmlSerializerFormatAttribute ayarlayarak Style
(kullanırkenXmlSerializer) bunu yapabilirsiniz.
Ayrıca, XmlSerializer iki serileştirilmiş XML biçimi de desteklenir: Literal
ve Encoded
. Literal
en yaygın kabul edilen formdur ve desteklerin DataContractSerializer tek biçimidir. Encoded
, SOAP belirtiminin 5. bölümünde açıklanan eski bir formdur ve yeni hizmetler için önerilmez. Moda geçmek için Encoded
özniteliğindeki Use
XmlSerializerFormatAttribute özelliğini olarak Encoded
ayarlayın.
Çoğu durumda ve Use
özellikleri için Style
varsayılan ayarları değiştirmemelisiniz.
Serileştirme İşlemini Denetleme
Verilerin seri hale getirilma şeklini özelleştirmek için çeşitli işlemler yapabilirsiniz.
Sunucu Serileştirme Ayarlar Değiştirme
Varsayılan DataContractSerializer kullanımda olduğunda, özniteliğini hizmete uygulayarak hizmetteki serileştirme işleminin ServiceBehaviorAttribute bazı yönlerini denetleyebilirsiniz. Özellikle, seri durumdan MaxItemsInObjectGraph
çıkarabileceği en fazla nesne DataContractSerializer sayısını sınırlayan kotayı ayarlamak için özelliğini kullanabilirsiniz. Yuvarlama IgnoreExtensionDataObject
sürüm oluşturma özelliğini kapatmak için özelliğini kullanabilirsiniz. Kotalar hakkında daha fazla bilgi için bkz . Veriler için Güvenlik Konuları. Yuvarlama hakkında daha fazla bilgi için bkz . İletme Uyumlu Veri Sözleşmeleri.
[ServiceBehavior(MaxItemsInObjectGraph=100000)]
public class MyDataService:IDataService
{
public DataPoint[] GetData()
{
// Implementation omitted
}
}
<ServiceBehavior(MaxItemsInObjectGraph:=100000)>
Public Class MyDataService Implements IDataService
Function GetData() As DataPoint()
‘ Implementation omitted
End Function
End Interface
Serileştirme Davranışları
WCF'de DataContractSerializerOperationBehavior , belirli bir işlem için hangi seri hale getiricinin XmlSerializerOperationBehavior kullanıldığına bağlı olarak otomatik olarak takılı olan ve şeklinde iki davranış vardır. Bu davranışlar otomatik olarak uygulandığından, normalde bunların farkında olmanız gerekmez.
Ancak, DataContractSerializerOperationBehavior
serileştirme işlemini özelleştirmek için kullanabileceğiniz , IgnoreExtensionDataObject
ve DataContractSurrogate
özelliklerine sahiptirMaxItemsInObjectGraph
. İlk iki özellik, önceki bölümde açıklananla aynı anlama sahiptir. serileştirme işlemini özelleştirmek ve genişletmek için güçlü bir mekanizma olan veri sözleşmesi yedeklerini etkinleştirmek için özelliğini kullanabilirsiniz DataContractSurrogate
. Daha fazla bilgi için bkz . Veri Sözleşmesi Vekilleri.
hem istemci hem de sunucu serileştirmesini özelleştirmek için kullanabilirsiniz DataContractSerializerOperationBehavior
. Aşağıdaki örnekte istemcideki kotanın MaxItemsInObjectGraph
nasıl artıracağınız gösterilmektedir.
ChannelFactory<IDataService> factory = new ChannelFactory<IDataService>(binding, address);
foreach (OperationDescription op in factory.Endpoint.Contract.Operations)
{
DataContractSerializerOperationBehavior dataContractBehavior =
op.Behaviors.Find<DataContractSerializerOperationBehavior>()
as DataContractSerializerOperationBehavior;
if (dataContractBehavior != null)
{
dataContractBehavior.MaxItemsInObjectGraph = 100000;
}
}
IDataService client = factory.CreateChannel();
Dim factory As ChannelFactory(Of IDataService) = New ChannelFactory(Of IDataService)(binding, address)
For Each op As OperationDescription In factory.Endpoint.Contract.Operations
Dim dataContractBehavior As DataContractSerializerOperationBehavior = op.Behaviors.Find(Of DataContractSerializerOperationBehavior)()
If dataContractBehavior IsNot Nothing Then
dataContractBehavior.MaxItemsInObjectGraph = 100000
End If
Next
Dim client As IDataService = factory.CreateChannel
Şirket içinde barındırılan örnekte hizmetteki eşdeğer kod aşağıdadır:
ServiceHost serviceHost = new ServiceHost(typeof(IDataService))
foreach (ServiceEndpoint ep in serviceHost.Description.Endpoints)
{
foreach (OperationDescription op in ep.Contract.Operations)
{
DataContractSerializerOperationBehavior dataContractBehavior =
op.Behaviors.Find<DataContractSerializerOperationBehavior>()
as DataContractSerializerOperationBehavior;
if (dataContractBehavior != null)
{
dataContractBehavior.MaxItemsInObjectGraph = 100000;
}
}
}
serviceHost.Open();
Dim serviceHost As ServiceHost = New ServiceHost(GetType(IDataService))
For Each ep As ServiceEndpoint In serviceHost.Description.Endpoints
For Each op As OperationDescription In ep.Contract.Operations
Dim dataContractBehavior As DataContractSerializerOperationBehavior = op.Behaviors.Find(Of DataContractSerializerOperationBehavior)()
If dataContractBehavior IsNot Nothing Then
dataContractBehavior.MaxItemsInObjectGraph = 100000
End If
Next
Next
serviceHost.Open()
Web'de barındırılan durumda, yeni ServiceHost
bir türetilmiş sınıf oluşturmanız ve bunu takmak için bir hizmet ana bilgisayar fabrikası kullanmanız gerekir.
Yapılandırmada Serileştirme Ayarlar Denetleme
MaxItemsInObjectGraph
veIgnoreExtensionDataObject
, aşağıdaki örnekte gösterildiği gibi uç nokta veya hizmet davranışı kullanılarak dataContractSerializer
yapılandırma aracılığıyla denetlenebilir.
<configuration>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="LargeQuotaBehavior">
<dataContractSerializer
maxItemsInObjectGraph="100000" />
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<endpoint address="http://example.com/myservice"
behaviorConfiguration="LargeQuotaBehavior"
binding="basicHttpBinding" bindingConfiguration=""
contract="IDataService"
name="" />
</client>
</system.serviceModel>
</configuration>
Paylaşılan Tür Serileştirme, Nesne Grafı Koruma ve Özel Seri Hale Getiriciler
, DataContractSerializer .NET türü adlarını değil veri sözleşmesi adlarını kullanarak seri hale getirmektedir. Bu, hizmet odaklı mimari ilkeleriyle tutarlıdır ve büyük ölçüde esneklik sağlar; .NET türleri, kablo sözleşmesini etkilemeden değişebilir. Nadir durumlarda, .NET Framework uzaktan iletişim teknolojisine benzer şekilde gerçek .NET türü adlarını seri hale getirmek ve böylece istemci ile sunucu arasında sıkı bir bağlantı oluşturmak isteyebilirsiniz. Bu, genellikle .NET Framework uzaktan iletişiminden WCF'ye geçiş sırasında oluşan nadir durumlar dışında önerilen bir uygulama değildir. Bu durumda, sınıfı yerine sınıfını DataContractSerializer kullanmanız NetDataContractSerializer gerekir.
normalde DataContractSerializer nesne grafiklerini nesne ağaçları olarak serileştirir. Başka bir ifadeyle, aynı nesneye birden çok kez başvurulursa, birden çok kez serileştirilir. Örneğin, ve shipTo
adlı billTo
Adres türünde iki alanı olan bir PurchaseOrder
örneği düşünün. Her iki alan da aynı Adres örneğine ayarlanırsa, serileştirme ve seri durumdan çıkarma işleminden sonra iki özdeş Adres örneği vardır. Bunun nedeni nesne graflarını XML'de temsil etmenin standart bir birlikte çalışılabilir yolu olmamasıdır (ve üzerindeki önceki bölümde Style
Use
açıklandığı gibi üzerinde XmlSerializerbulunan eski SOAP kodlanmış standardı hariç). Nesne grafiklerini ağaç olarak seri hale getirmenin bazı dezavantajları vardır, örneğin döngüsel başvurulara sahip grafikler seri hale getirilemez. Bazen, birlikte çalışamaz olsa bile gerçek nesne grafiği serileştirmesine geçmek gerekir. Bu, parametresi olarak ayarlanmış true
şekilde oluşturularak DataContractSerializerpreserveObjectReferences
yapılabilir.
Bazen, yerleşik serileştiriciler senaryonuz için yeterli değildir. Çoğu durumda, hem hem de DataContractSerializer türetilen soyutlama özelliğini NetDataContractSerializer kullanmaya XmlObjectSerializer devam edebilirsiniz.
Önceki üç durum (.NET tür koruması, nesne grafı koruması ve tamamen özel XmlObjectSerializer
tabanlı serileştirme) tümü özel bir seri hale getiricinin takılı olmasını gerektirir. Bunun için aşağıdaki adımları gerçekleştirin:
'den DataContractSerializerOperationBehaviortüretilen kendi davranışınızı yazın.
Kendi seri hale getiricinizi döndürmek için iki
CreateSerializer
yöntemi geçersiz kılın (NetDataContractSerializerDataContractSerializerolarak ayarlanmıştrue
olanpreserveObjectReferences
, veya kendi özel XmlObjectSerializeryönteminiz).Hizmet ana bilgisayarını açmadan veya istemci kanalı oluşturmadan önce, mevcut DataContractSerializerOperationBehavior davranışı kaldırın ve önceki adımlarda oluşturduğunuz özel türetilmiş sınıfı takın.
Gelişmiş serileştirme kavramları hakkında daha fazla bilgi için bkz . Serileştirme ve Seri Durumdan Çıkarma.