데이터 계약 사용

데이터 계약 은 서비스와 클라이언트 사이에서 교환할 데이터를 추상적으로 설명한 공식 계약입니다. 즉, 클라이언트와 서비스가 같은 형식을 공유하지 않고 같은 데이터 계약만 공유해도 통신이 가능합니다. 데이터 계약에서는 각 매개 변수 또는 반환 형식에 대해 교환을 위해 serialize(XML로 변환)해야 할 데이터를 세밀하게 정의합니다.

데이터 계약 기본 사항

WCF(Windows Communication Foundation)에서는 기본적으로 데이터 계약 직렬 변환기라는 직렬화 엔진을 사용하여 데이터를 직렬화 및 역직렬화(XML로 변환 및 변환 해제)합니다. 정수 및 문자열과 같은 모든 .NET Framework 기본 형식 외에도 DateTimeXmlElement와 같이 기본 형식으로 취급되는 일부 형식을 별도의 준비 없이 직렬화할 수 있으며 기본 데이터 계약이 있는 것으로 간주할 수 있습니다. 많은 .NET Framework 형식에도 기존 데이터 계약이 있습니다. 모든 serialize 가능 형식의 목록은 Types Supported by the Data Contract Serializer을 참조하십시오.

새로 만든 복합 형식을 serialize하려면 데이터 계약이 정의되어 있어야 합니다. 기본적으로 DataContractSerializer 는 데이터 계약을 유추하고 모든 공개 형식을 serialize합니다. 이 경우 형식의 모든 공개 읽기/쓰기 속성과 필드가 serialize됩니다. IgnoreDataMemberAttribute를 사용하여 멤버의 serialization을 취소할 수 있습니다. 또한 DataContractAttributeDataMemberAttribute 특성을 사용하여 데이터 계약을 명시적으로 만들 수도 있습니다. 보통은 형식에 DataContractAttribute 특성을 적용하면 됩니다. 이 특성을 클래스, 구조 및 열거에 적용할 수 있습니다. 그런 다음 데이터 계약 형식의 각 멤버에 DataMemberAttribute 특성을 적용하여 데이터 멤버이며 serialize되어야 한다는 것을 나타내야 합니다. 자세한 내용은 직렬화 가능 형식을 참조하세요.

예시

다음 예제에서는 ServiceContractAttributeOperationContractAttribute 특성이 명시적으로 적용된 서비스 계약(인터페이스)을 보여 줍니다. 이 예제는 기본 형식에는 데이터 계약이 필요 없지만 복합 형식에는 필요하다는 것을 보여 줍니다.

[ServiceContract]
public interface ISampleInterface
{
    // No data contract is required since both the parameter
    // and return types are primitive types.
    [OperationContract]
    double SquareRoot(int root);

    // No Data Contract required because both parameter and return
    // types are marked with the SerializableAttribute attribute.
    [OperationContract]
    System.Drawing.Bitmap GetPicture(System.Uri pictureUri);

    // The MyTypes.PurchaseOrder is a complex type, and thus
    // requires a data contract.
    [OperationContract]
    bool ApprovePurchaseOrder(MyTypes.PurchaseOrder po);
}
<ServiceContract()> _
Public Interface ISampleInterface
    ' No data contract is required since both the parameter and return 
    ' types are both primitive types.
    <OperationContract()> _
    Function SquareRoot(ByVal root As Integer) As Double

    ' No Data Contract required because both parameter and return 
    ' types are marked with the SerializableAttribute attribute.
    <OperationContract()> _
    Function GetPicture(ByVal pictureUri As System.Uri) As System.Drawing.Bitmap

    ' The MyTypes.PurchaseOrder is a complex type, and thus 
    ' requires a data contract.
    <OperationContract()> _
    Function ApprovePurchaseOrder(ByVal po As MyTypes.PurchaseOrder) As Boolean
End Interface

다음 예제에서는 클래스 및 해당 멤버에 MyTypes.PurchaseOrderDataContractAttribute 특성을 적용하여 DataMemberAttribute 형식의 데이터 계약을 만드는 방법을 보여 줍니다.

namespace MyTypes
{
    [DataContract]
    public class PurchaseOrder
    {
        private int poId_value;

        // Apply the DataMemberAttribute to the property.
        [DataMember]
        public int PurchaseOrderId
        {

            get { return poId_value; }
            set { poId_value = value; }
        }
    }
}
Namespace MyTypes
    <System.Runtime.Serialization.DataContractAttribute()> _
    Public Class PurchaseOrder
        Private poId_value As Integer

        ' Apply the DataMemberAttribute to the property.

        <DataMember()> _
        Public Property PurchaseOrderId() As Integer

            Get
                Return poId_value
            End Get
            Set
                poId_value = value
            End Set
        End Property
    End Class
End Namespace

주의

다음 참고 사항에서는 데이터 계약을 만들 때 고려해야 할 항목을 소개합니다.

  • IgnoreDataMemberAttribute 특성은 표시되지 않은 형식으로 사용한 경우에만 적용됩니다. 여기에는 DataContractAttribute, SerializableAttribute, CollectionDataContractAttribute또는 EnumMemberAttribute 특성 중 하나로 표시되지 않은 형식이나 다른 방법(예: IXmlSerializable)으로 serialize할 수 있는 것으로 표시된 형식이 포함됩니다.

  • 필드 및 속성에 DataMemberAttribute 특성을 적용할 수 있습니다.

  • 멤버 액세스 가능성 수준(internal, private, protected 또는 public)은 데이터 계약에 어떤 방식으로도 영향을 주지 않습니다.

  • DataMemberAttribute 특성은 정적 멤버에 적용하면 무시됩니다.

  • serialization을 수행하는 동안 속성 데이터 멤버에 대해 property-get 코드를 호출하여 serialize할 속성의 값을 가져옵니다.

  • 역직렬화를 수행하는 동안 초기화되지 않은 개체가 형식에서 생성자를 호출하지 않고 먼저 만들어집니다. 그러면 모든 데이터 멤버가 역직렬화됩니다.

  • deserialization을 수행하는 동안 속성 데이터 멤버에 대해 property-set 코드를 호출하여 역직렬화할 값으로 속성을 설정합니다.

  • 유효한 데이터 계약에서는 모든 데이터 멤버를 serialize할 수 있어야 합니다. 모든 serialize 가능 형식의 목록은 Types Supported by the Data Contract Serializer을 참조하십시오.

    제네릭 형식은 비제네릭 형식과 완전히 같은 방식으로 처리됩니다. 제네릭 매개 변수에 대한 특수 요구 사항은 없습니다. 다음 형식을 예로 들 수 있습니다.

[DataContract]
public class MyGenericType1<T>
{
    // Code not shown.
}
<DataContract()> _
Public Class MyGenericType1(Of T)
    ' Code not shown.
End Class

제네릭 형식 매개 변수(T)에 사용된 형식이 serialize 가능한지 여부에 관계없이 이 형식은 serialize할 수 있습니다. 모든 데이터 멤버를 serialize할 수 있어야 하기 때문에 다음 코드에 표시된 것과 같이 제네릭 형식 매개 변수도 serialize할 수 있는 경우에만 다음 형식을 serialize할 수 있습니다.

[DataContract]
public class MyGenericType2<T>
{
    [DataMember]
    T theData;
}
<DataContract()> _
Public Class MyGenericType2(Of T)
    <DataMember()> _
    Dim theData As T
End Class

데이터 계약을 정의하는 WCF 서비스의 전체 코드 샘플을 보려면 Basic Data Contract 샘플을 참조하십시오.

참고 항목