다음을 통해 공유


서비스 계약에서 데이터 전송 지정

WCF(Windows Communication Foundation)는 메시징 인프라로 간주할 수 있습니다. 서비스 작업은 메시지를 수신하고, 처리하고, 메시지를 보낼 수 있습니다. 메시지는 작업 계약을 사용하여 설명됩니다. 예를 들어 다음 계약을 고려합니다.

[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  

여기서 GetAirfare 작업은 fromCitytoCity에 대한 정보를 포함한 메시지를 수신하고, 숫자가 포함된 메시지를 반환합니다.

이 항목에서는 작업 계약에서 메시지를 설명할 수 있는 다양한 방법을 설명합니다.

매개 변수를 사용하여 메시지 설명

메시지를 설명하는 가장 간단한 방법은 매개 변수 목록과 반환 값을 사용하는 것입니다. 앞의 예제 fromCity 에서는 요청 메시지를 설명하는 데 문자열 매개 변수와 toCity 문자열 매개 변수를 사용했으며, float 반환 값은 회신 메시지를 설명하는 데 사용되었습니다. 반환 값만으로 회신 메시지를 설명하는 데 충분하지 않은 경우 out 매개 변수를 사용할 수 있습니다. 예를 들어, 다음 작업에는 fromCitytoCity이 요청 메시지에 있고, 숫자와 통화가 응답 메시지에 포함되어 있습니다.

[OperationContract]  
float GetAirfare(string fromCity, string toCity, out string currency);  
<OperationContract()>  
    Function GetAirfare(fromCity As String, toCity As String) As Double  

또한 참조 매개 변수를 사용하여 요청 및 회신 메시지 둘 다의 매개 변수 부분을 만들 수 있습니다. 매개 변수는 serialize할 수 있는 형식이어야 합니다(XML로 변환). 기본적으로 WCF는 클래스라는 DataContractSerializer 구성 요소를 사용하여 이 변환을 수행합니다. 대부분의 기본 형식(예: int, string, floatDateTime.)이 지원됩니다. 사용자 정의 형식에는 일반적으로 데이터 계약이 있어야 합니다. 자세한 내용은 데이터 계약 사용을 참조하세요.

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  

경우에 따라 DataContractSerializer는 형식을 직렬화하기에 충분하지 않습니다. WCF는 매개변수를 직렬화하는 데 사용할 수 있는 대체 직렬화 엔진 XmlSerializer을 지원합니다. XmlSerializer을 사용하면 XmlAttributeAttribute 같은 특성을 통해 결과 XML에 대해 더 많은 제어를 할 수 있습니다. XmlSerializer을(를) 특정 작업이나 전체 서비스에 사용하도록 전환하려면 해당 작업이나 서비스에 XmlSerializerFormatAttribute 특성을 적용하세요. 다음은 그 예입니다.

[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  

자세한 내용은 XmlSerializer 클래스 사용을 참조하세요. 해당 항목에 XmlSerializer 자세히 설명된 대로 특정 이유가 없는 한 여기에 표시된 대로 수동으로 전환하는 것은 권장되지 않습니다.

.NET 매개 변수 이름을 계약 이름에서 격리하려면 특성을 사용하고 MessageParameterAttribute 속성을 사용하여 Name 계약 이름을 설정할 수 있습니다. 예를 들어 다음 작업 계약은 이 항목의 첫 번째 예제와 동일합니다.

[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  

빈 메시지 설명

입력 또는 참조 매개 변수가 없으면 빈 요청 메시지를 설명할 수 있습니다. 예를 들어 C#에서는 다음을 수행합니다.

[OperationContract]

public int GetCurrentTemperature();

예를 들어 Visual Basic에서는 다음을 수행합니다.

<OperationContract()>

Function GetCurrentTemperature() as Integer

반환 형식이 있고 출력 또는 참조 매개 변수가 없으면 void 빈 회신 메시지를 설명할 수 있습니다. 예를 들어:

[OperationContract]  
public void SetTemperature(int temperature);  
<OperationContract()>  
Sub SetTemperature(temperature As Integer)  

이는 다음과 같은 단방향 작업과 다릅니다.

[OperationContract(IsOneWay=true)]  
public void SetLightbulbStatus(bool isOn);  
<OperationContract(IsOneWay:=True)>  
Sub SetLightbulbStatus(isOne As Boolean)  

작업은 SetTemperatureStatus 빈 메시지를 반환합니다. 대신 입력 메시지를 처리하는 데 문제가 있는 경우 오류를 반환할 수 있습니다. SetLightbulbStatus 작업은 아무것도 반환하지 않습니다. 이 작업에서 오류 조건을 전달할 수 있는 방법은 없습니다.

메시지 계약을 사용하여 메시지 설명

단일 형식을 사용하여 전체 메시지를 나타낼 수 있습니다. 이 목적을 위해 데이터 계약을 사용할 수 있지만 이 작업을 수행하는 권장 방법은 메시지 계약을 사용하는 것입니다. 이렇게 하면 결과 XML에서 불필요한 래핑 수준을 방지할 수 있습니다. 또한 메시지 계약을 사용하면 결과 메시지를 보다 효율적으로 제어할 수 있습니다. 예를 들어 메시지 본문에 있어야 하는 정보와 메시지 헤더에 있어야 하는 정보를 결정할 수 있습니다. 다음 예제에서는 메시지 계약의 사용을 보여 줍니다.

[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  

자세한 내용은 메시지 계약 사용을 참조하세요.

이전 예제에서 클래스는 DataContractSerializer 여전히 기본적으로 사용됩니다. 이 클래스는 XmlSerializer 메시지 계약과 함께 사용할 수도 있습니다. 이렇게 하려면 작업 또는 계약에 특성을 적용 XmlSerializerFormatAttribute 하고 메시지 헤더 및 본문 멤버의 XmlSerializer 클래스와 호환되는 형식을 사용합니다.

스트림을 사용하여 메시지 설명

작업에서 메시지를 설명하는 또 다른 방법은 작업 계약에서 클래스 또는 파생 클래스 중 하나를 사용하거나 메시지 계약 본문 멤버로 사용하는 Stream 것입니다(이 경우 유일한 멤버여야 합니다). 들어오는 메시지의 경우 형식은 파생 클래스를 사용할 수 없는 형식이어야 Stream합니다.

WCF는 직렬 변환기를 호출하는 대신 스트림에서 데이터를 검색하여 보내는 메시지에 직접 넣거나 들어오는 메시지에서 데이터를 검색하여 스트림에 직접 넣습니다. 다음 샘플에서는 스트림의 사용을 보여 줍니다.

[OperationContract]  
public Stream DownloadFile(string fileName);  
<OperationContract()>  
Function DownloadFile(fileName As String) As String  

메시지 본문에서는 Stream를 스트림 데이터와 비스트림 데이터를 결합할 수 없습니다. 메시지 계약을 사용하여 추가 데이터를 메시지 헤더에 넣습니다. 다음 예제에서는 작업 계약을 정의할 때 잘못된 스트림 사용을 보여 줍니다.

//Incorrect:  
// [OperationContract]  
// public void UploadFile (string fileName, Stream fileData);  
'Incorrect:  
    '<OperationContract()>  
    Public Sub UploadFile(fileName As String, fileData As StreamingContext)  

다음 샘플에서는 작업 계약을 정의할 때 스트림을 올바르게 사용하는 방법을 보여 줍니다.

[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  

자세한 내용은 큰 데이터 및 스트리밍을 참조하세요.

메시지 클래스 사용

보내거나 받은 메시지에 대해 프로그래밍 방식으로 완전히 제어하려면 다음 예제 코드와 같이 클래스를 직접 사용할 Message 수 있습니다.

[OperationContract]  
public void LogMessage(Message m);  
<OperationContract()>  
Sub LogMessage(m As Message)  

이 시나리오는 메시지 클래스 사용에 자세히 설명된 고급 시나리오입니다.

오류 메시지 설명

반환 값과 출력 또는 참조 매개 변수로 설명된 메시지 외에도 단방향이 아닌 모든 작업은 정상 응답 메시지와 오류 메시지라는 두 개 이상의 가능한 메시지를 반환할 수 있습니다. 다음 작업 계약을 고려합니다.

[OperationContract]  
float GetAirfare(string fromCity, string toCity, DateTime date);  
<OperationContract()>  
Function GetAirfare(fromCity As String, toCity As String, date as DateTime)  

이 작업은 숫자가 포함된 float 일반 메시지 또는 오류 코드와 설명이 포함된 오류 메시지를 반환할 수 있습니다. 서비스 구현에서 throw FaultException 하여 이 작업을 수행할 수 있습니다.

특성을 사용하여 FaultContractAttribute 가능한 추가 오류 메시지를 지정할 수 있습니다. 다음 예제 코드에 표시된 대로, 추가적인 오류는 DataContractSerializer을 사용하여 직렬화할 수 있어야 합니다.

[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  

이러한 추가 오류는 적절한 데이터 계약 타입을 던져 FaultException<TDetail> 생성할 수 있습니다. 자세한 내용은 예외 및 오류 처리를 참조하세요.

클래스를 XmlSerializer 사용하여 오류를 설명할 수 없습니다. 오류 XmlSerializerFormatAttribute 계약에 아무런 영향을 미치지 않습니다.

파생 형식 사용

작업 또는 메시지 계약에서 기본 형식을 사용한 다음 실제로 작업을 호출할 때 파생 형식을 사용할 수 있습니다. 이 경우, 파생 형식을 사용할 수 있도록 ServiceKnownTypeAttribute 속성 또는 다른 대체 메커니즘을 사용해야 합니다. 다음 작업을 고려합니다.

[OperationContract]  
public bool IsLibraryItemAvailable(LibraryItem item);  
<OperationContract()>  
    Function IsLibraryItemAvailable(item As LibraryItem) As Boolean  

BookMagazine 두 형식이 LibraryItem에서 파생된다고 가정합니다. 작업에서 이러한 형식을 IsLibraryItemAvailable 사용하려면 다음과 같이 작업을 변경할 수 있습니다.

[OperationContract]

[ServiceKnownType(typeof(Book))]

[ServiceKnownType(typeof(Magazine))]

public bool IsLibraryItemAvailable(LibraryItem item);

다음 예제 코드와 같이 기본 KnownTypeAttribute이 사용 중일 때, 대신 DataContractSerializer 특성을 사용할 수 있습니다.

[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  

XmlIncludeAttribute를 사용할 때 XmlSerializer 특성을 사용할 수 있습니다.

작업 또는 전체 서비스에 특성을 적용 ServiceKnownTypeAttribute 할 수 있습니다. 특성과 마찬가지로 KnownTypeAttribute 알려진 형식 목록을 가져오기 위해 호출할 메서드의 형식 또는 이름을 허용합니다. 자세한 내용은 데이터 계약 알려진 형식을 참조하세요.

사용 및 스타일 지정

WSDL(Web Services Description Language)을 사용하여 서비스를 설명할 때 일반적으로 사용되는 두 가지 스타일은 문서 및 RPC(원격 프로시저 호출)입니다. 문서 스타일에서 전체 메시지 본문은 스키마를 사용하여 설명하고 WSDL은 해당 스키마 내의 요소를 참조하여 다양한 메시지 본문 부분을 설명합니다. RPC 스타일에서 WSDL은 요소가 아닌 각 메시지 부분에 대한 스키마 형식을 참조합니다. 경우에 따라 이러한 스타일 중 하나를 수동으로 선택해야 합니다. DataContractFormatAttribute 속성을 적용하고 Style가 사용 중일 때 DataContractSerializer 속성을 설정하거나, Style를 사용할 때 XmlSerializerFormatAttribute 특성에 XmlSerializer을 설정하여 이 작업을 수행할 수 있습니다.

또한, XmlSerializerLiteralEncoded라는 두 가지 직렬화된 XML 형식을 지원합니다. Literal 는 가장 일반적으로 허용되는 양식이며 지원되는 유일한 양식 DataContractSerializer 입니다. Encoded 는 SOAP 사양의 섹션 5에 설명된 레거시 양식이며 새 서비스에는 권장되지 않습니다. Encoded 모드로 전환하려면 Use 특성의 XmlSerializerFormatAttribute 속성을 Encoded로 설정합니다.

대부분의 경우 StyleUse 속성에 대한 기본 설정을 변경해서는 안 됩니다.

직렬화 프로세스 제어

데이터를 직렬화하는 방식을 사용자 지정하기 위해 여러 가지 작업을 수행할 수 있습니다.

서버 Serialization 설정 변경

기본 DataContractSerializer 이 사용 중인 경우, 서비스에 ServiceBehaviorAttribute 특성을 적용하여 시리얼라이제이션 과정의 일부 측면을 제어할 수 있습니다. 특히 MaxItemsInObjectGraph 속성을 사용하여 DataContractSerializer가 역직렬화하는 개체의 최대 수를 제한하는 할당량을 설정할 수 있습니다. 이 IgnoreExtensionDataObject 속성을 사용하여 라운드트립 버전 관리 기능을 끌 수 있습니다. 할당량에 대한 자세한 내용은 데이터에 대한 보안 고려 사항을 참조하세요. 라운드트립에 대한 자세한 내용은 Forward-Compatible 데이터 계약을 참조하세요.

[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  

Serialization 동작 방식

WCF DataContractSerializerOperationBehaviorXmlSerializerOperationBehavior 에서는 특정 작업에 사용 중인 serializer에 따라 자동으로 연결되는 두 가지 동작을 사용할 수 있습니다. 이러한 동작은 자동으로 적용되므로 일반적으로 이러한 동작을 인식할 필요가 없습니다.

그러나 DataContractSerializerOperationBehavior에는 serialization 프로세스를 사용자 지정하는 데 사용할 수 있는 MaxItemsInObjectGraph, IgnoreExtensionDataObject, 및 DataContractSurrogate 속성이 있습니다. 처음 두 속성은 이전 섹션에서 설명한 것과 동일한 의미를 갖습니다. 직렬화 프로세스를 사용자 지정하고 확장하기 위한 강력한 메커니즘인 데이터 계약 서로게이트를 사용하도록 설정하려면 이 속성을 사용할 DataContractSurrogate 수 있습니다. 자세한 내용은 데이터 계약 서로게이트를 참조하세요.

클라이언트 및 서버 직렬화를 모두 사용자 지정하는 데 DataContractSerializerOperationBehavior를 사용할 수 있습니다. 다음 예제에서는 클라이언트의 할당량을 MaxItemsInObjectGraph 늘리는 방법을 보여 있습니다.

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  

다음은 자체 호스팅 사례의 서비스에 해당하는 코드입니다.

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()  

웹 호스팅 사례에서 새 ServiceHost 파생 클래스를 만들고 서비스 호스트 팩터리를 사용하여 연결해야 합니다.

구성에서 직렬화 설정 제어

MaxItemsInObjectGraphIgnoreExtensionDataObject는 아래 예시와 같이 'dataContractSerializer' 엔드포인트나 서비스 동작을 사용하여 구성을 통해 제어할 수 있습니다.

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

공유 형식 직렬화, 개체 그래프 보존 및 사용자 지정 직렬 변환기

. DataContractSerializer NET 형식 이름이 아닌 데이터 계약 이름을 사용하여 직렬화합니다. 이는 서비스 지향 아키텍처 테넌트와 일치하며 뛰어난 유연성을 제공합니다. .NET 형식은 유선 계약에 영향을 주지 않고도 변경될 수 있습니다. 드물게 실제 .NET 형식 이름을 직렬화하여 .NET Framework 원격 기술과 유사하게 클라이언트와 서버 간의 긴밀한 결합을 도입할 수 있습니다. .NET Framework 원격에서 WCF로 마이그레이션할 때 일반적으로 발생하는 드문 경우를 제외하고는 권장되지 않습니다. 이 경우 NetDataContractSerializer 클래스를 DataContractSerializer 클래스 대신 사용해야 합니다.

DataContractSerializer 일반적으로 개체 그래프를 개체 트리로 직렬화합니다. 즉, 동일한 개체를 두 번 이상 참조하는 경우 두 번 이상 serialize됩니다. 예를 들어, PurchaseOrder 인스턴스에는 Address 유형의 billTo 필드와 shipTo 필드가 두 개 있습니다. 두 필드가 모두 동일한 주소 인스턴스로 설정된 경우 serialization 및 deserialization 후에 두 개의 동일한 주소 인스턴스가 있습니다. 이 작업은 XML에서 개체 그래프를 나타내는 표준 상호 운용 가능한 방법이 없기 때문에 수행됩니다. 다만, 이전 섹션에서 XmlSerializer, Style에 설명된 대로 Use에서 사용할 수 있는 레거시 SOAP 인코딩 표준은 예외입니다. 트리로 개체 그래프를 직렬화하면 특정 단점이 있습니다. 예를 들어 순환 참조가 있는 그래프는 serialize할 수 없습니다. 경우에 따라 상호 운용할 수 없더라도 진정한 개체 그래프 직렬화로 전환해야 할 필요가 있습니다. DataContractSerializerpreserveObjectReferences 매개 변수가 true로 설정된 상태에서 사용할 수 있습니다.

경우에 따라 기본 제공 직렬 변환기는 시나리오에 충분하지 않습니다. 대부분의 경우 XmlObjectSerializerDataContractSerializer가 파생되는 NetDataContractSerializer 추상화를 계속 사용할 수 있습니다.

이전의 세 가지 사례(.NET 형식 보존, 개체 그래프 보존 및 완전히 사용자 지정 XmlObjectSerializer기반 직렬화)는 모두 사용자 지정 serializer를 연결해야 합니다. 그렇게 하려면 다음 단계를 수행합니다.

  1. DataContractSerializerOperationBehavior에서 파생된 귀하의 고유한 행동을 직접 작성하세요.

  2. CreateSerializer 메서드를 재정의하여 serializer를 직접 반환합니다. 이때 사용할 수 있는 것은 NetDataContractSerializer, DataContractSerializer이(가) preserveObjectReferences로 설정된 true, 또는 사용자 고유의 XmlObjectSerializer입니다.

  3. 서비스 호스트를 열거나 클라이언트 채널을 만들기 전에 기존 동작을 DataContractSerializerOperationBehavior 제거하고 이전 단계에서 만든 사용자 지정 파생 클래스를 연결합니다.

고급 serialization 개념에 대한 자세한 내용은 Serialization 및 Deserialization을 참조하세요.

참고하십시오