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 toCityhakkı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 (, , floatve DateTime. gibiintstring) 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 XmlAttributeAttributeolanak 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 Magazineolmak üzere iki türün Book türünden LibraryItemtü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 UseXmlSerializerFormatAttribute özelliğini olarak Encodedayarlayı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 , IgnoreExtensionDataObjectve 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 shipToadlı 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 StyleUseaçı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 XmlObjectSerializertabanlı 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:

  1. 'den DataContractSerializerOperationBehaviortüretilen kendi davranışınızı yazın.

  2. Kendi seri hale getiricinizi döndürmek için iki CreateSerializer yöntemi geçersiz kılın (NetDataContractSerializerDataContractSerializerolarak ayarlanmış trueolan preserveObjectReferences , veya kendi özel XmlObjectSerializeryönteminiz).

  3. 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.

Ayrıca bkz.