다음을 통해 공유


데이터 계약 이름

클라이언트와 서비스가 동일한 형식을 공유하지 않는 경우가 있습니다. 데이터 계약이 양쪽에 동일한 경우 데이터를 서로 전달할 수 있습니다. 데이터 계약 동등성은 데이터 계약 및 데이터 멤버 이름을 기반으로 하므로 형식 및 멤버를 해당 이름에 매핑하는 메커니즘이 제공됩니다. 이 항목에서는 이름을 만들 때 데이터 계약의 명명 규칙과 WCF(Windows Communication Foundation) 인프라의 기본 동작에 대해 설명합니다.

기본 규칙

데이터 계약 명명과 관련된 기본 규칙은 다음과 같습니다.

  • 정규화된 데이터 계약 이름은 네임스페이스와 이름으로 구성됩니다.

  • 데이터 멤버에는 이름만 있지만 네임스페이스는 없습니다.

  • 데이터 계약을 처리할 때, WCF 인프라는 네임스페이스와 데이터 계약 및 데이터 멤버의 이름에 대해 대소문자를 구분합니다.

데이터 계약 네임스페이스

데이터 계약 네임스페이스는 URI(Uniform Resource Identifier) 형식을 사용합니다. URI는 절대 또는 상대일 수 있습니다. 기본적으로 특정 형식에 대한 데이터 계약에는 해당 형식의 CLR(공용 언어 런타임) 네임스페이스에서 가져온 네임스페이스가 할당됩니다.

기본적으로 지정된 CLR 네임스페이스( Clr.Namespace 형식)는 네임스페이스에 http://schemas.datacontract.org/2004/07/Clr.Namespace매핑됩니다. 이 기본값을 재정의하려면 전체 모듈 또는 어셈블리에 ContractNamespaceAttribute 특성을 적용합니다. 또는 각 형식에 대한 데이터 계약 네임스페이스를 제어하려면 NamespaceDataContractAttribute 속성을 설정하십시오.

비고

네임스페이 http://schemas.microsoft.com/2003/10/Serialization 스는 예약되어 있으며 데이터 계약 네임스페이스로 사용할 수 없습니다.

비고

선언이 포함된 delegate 데이터 계약 형식에서는 기본 네임스페이스를 재정의할 수 없습니다.

데이터 계약 이름

지정된 형식에 대한 데이터 계약의 기본 이름은 해당 형식의 이름입니다. 기본값을 재정의하려면 NameDataContractAttribute 속성을 대체 이름으로 설정합니다. 제네릭 형식에 대한 특수 규칙은 이 항목의 뒷부분에 있는 "제네릭 형식에 대한 데이터 계약 이름"에 설명되어 있습니다.

데이터 멤버 이름

지정된 필드 또는 속성에 대한 데이터 멤버의 기본 이름은 해당 필드 또는 속성의 이름입니다. 기본값을 재정의하려면 NameDataMemberAttribute 속성을 대체 값으로 설정합니다.

예시

다음 예제에서는 데이터 계약 및 데이터 멤버의 기본 명명 동작을 재정의하는 방법을 보여 줍니다.

// This overrides the standard namespace mapping for all contracts
// in Contoso.CRM.
[assembly: ContractNamespace("http://schemas.example.com/crm",
   ClrNamespace = "Contoso.CRM")]
namespace Contoso.CRM
{
    // The namespace is overridden to become:
    // http://schemas.example.com/crm.
    // But the name is the default "Customer".
    [DataContract]
    public class Customer
    {
        // Code not shown.
    }
}
namespace Contoso.OrderProc
{
    [DataContract]
    public class PurchaseOrder
    {
        // This data member is named "Amount" by default.
        [DataMember]
        public double Amount;

        // The default is overridden to become "Address".
        [DataMember(Name = "Address")]
        public string Ship_to;
    }
    // The namespace is the default value:
    // http://schemas.datacontract.org/2004/07/Contoso.OrderProc
    // The name is "PurchaseOrder" instead of "MyInvoice".
    [DataContract(Name = "PurchaseOrder")]
    public class MyInvoice
    {
        // Code not shown.
    }

    // The contract name is "Payment" instead of "MyPayment"
    // and the Namespace is "http://schemas.example.com" instead
    // of the default.
    [DataContract(Name = "Payment",
        Namespace = "http://schemas.example.com")]
    public class MyPayment
    {
        // Code not shown.
    }
}
' This overrides the standard namespace mapping for all contracts 
' in Contoso.CRM. 
<Assembly: ContractNamespace("http://schemas.example.com/crm", _
ClrNamespace:="Contoso.CRM")>
Namespace Contoso.CRM
    ' The namespace is overridden to become: 
    ' http://schemas.example.com/crm.
    ' But the name is the default "Customer".
    <DataContract()> _
    Public Class Customer
        ' Code not shown.
    End Class
End Namespace

Namespace Contoso.OrderProc
    <DataContract()> _
    Public Class PurchaseOrder
        ' This data member is named "Amount" by default.
        <DataMember()> _
        Public Amount As Double

        ' The default is overridden to become "Address".
        <DataMember(Name:="Address")> _
        Public Ship_to As String
    End Class

    ' The namespace is the default value:
    ' http://schemas.datacontract.org/2004/07/Contoso.OrderProc
    ' The name is "PurchaseOrder" instead of "MyInvoice".
    <DataContract(Name:="PurchaseOrder")> _
    Public Class MyInvoice
        ' Code not shown.
    End Class

    ' The contract name is "Payment" instead of "MyPayment" 
    ' and the Namespace is "http://schemas.example.com" instead
    ' of the default.
    <DataContract(Name:="Payment", [Namespace]:="http://schemas.example.com")> _
    Public Class MyPayment
        ' Code not shown.
    End Class
End Namespace

제네릭 형식의 데이터 계약 이름

제네릭 형식의 데이터 계약 이름을 결정하는 특수 규칙이 있습니다. 이러한 규칙은 동일한 제네릭 형식의 닫힌 두 제네릭 간에 데이터 계약 이름 충돌을 방지하는 데 도움이 됩니다.

기본적으로 제네릭 형식의 데이터 계약 이름은 형식의 이름이며, 그 뒤에 문자열 "Of", 제네릭 매개 변수의 데이터 계약 이름, 제네릭 매개 변수의 데이터 계약 네임스페이스를 사용하여 계산된 해시 가 뒤따릅니다. 해시는 데이터 조각을 고유하게 식별하는 "지문"으로 작동하는 수학 함수의 결과입니다. 모든 제네릭 매개 변수가 기본 형식이면 해시가 생략됩니다.

예를 들어 다음 예제의 형식을 참조하세요.

[DataContract]
public class Drawing<Shape, Brush>
{
    // Code not shown.
}

[DataContract(Namespace = "urn:shapes")]
public class Square
{
    // Code not shown.
}

[DataContract(Name = "RedBrush", Namespace = "urn:default")]
public class RegularRedBrush
{
    // Code not shown.
}

[DataContract(Name = "RedBrush", Namespace = "urn:special")]
public class SpecialRedBrush
{
    // Code not shown.
}
<DataContract()> _
Public Class Drawing(Of Shape, Brush)

    <DataContract([Namespace]:="urn:shapes")> _
    Public Class Square
        ' Code not shown.
    End Class


    <DataContract(Name:="RedBrush", [Namespace]:="urn:default")> _
    Public Class RegularRedBrush
        ' Code not shown.
    End Class

    <DataContract(Name:="RedBrush", [Namespace]:="urn:special")> _
    Public Class SpecialRedBrush
        ' Code not shown.
    End Class
End Class

이 예제에서 형식 Drawing<Square,RegularRedBrush> 에는 데이터 계약 이름 "DrawingOfSquareRedBrush5HWGAU6h"가 있습니다. 여기서 "5HWGAU6h"는 "urn:shapes" 및 "urn:default" 네임스페이스의 해시입니다. 형식 Drawing<Square,SpecialRedBrush> 에는 데이터 계약 이름 "DrawingOfSquareRedBrushjpB5LgQ_S"이 있습니다. 여기서 "jpB5LgQ_S"는 "urn:shapes" 및 "urn:special" 네임스페이스의 해시입니다. 해시를 사용하지 않으면 두 이름이 동일하므로 이름 충돌이 발생합니다.

제네릭 형식에 대한 데이터 계약 이름 사용자 지정

경우에 따라 앞에서 설명한 대로 제네릭 형식에 대해 생성된 데이터 계약 이름은 허용되지 않습니다. 예를 들어, 이름 충돌이 발생하지 않을 것을 미리 알고 해시를 제거하고 싶을 수 있습니다. 이 경우 속성을 사용하여 DataContractAttribute.Name 이름을 생성하는 다른 방법을 지정할 수 있습니다. 속성 내의 중괄호 안에 숫자를 사용하여 제네릭 매개 변수의 Name 데이터 계약 이름을 참조할 수 있습니다. (0은 첫 번째 매개 변수를 참조하고, 1은 두 번째 매개 변수를 참조하는 등). 중괄호 안에 숫자(#) 기호를 사용하여 해시를 참조할 수 있습니다. 이러한 각 참조를 여러 번 사용하거나 전혀 사용할 수 없습니다.

예를 들어 앞의 제네릭 Drawing 형식은 다음 예제와 같이 선언되었을 수 있습니다.

[DataContract(Name = "Drawing_using_{1}_brush_and_{0}_shape")]
public class Drawing<Shape, Brush>
{
    // Code not shown.
}
<DataContract(Name:="Drawing_using_{1}_brush_and_{0}_shape")> _
Public Class Drawing(Of Shape, Brush)
    ' Code not shown.
End Class

이 경우, 형식 Drawing<Square,RegularRedBrush>의 데이터 계약 이름은 "Drawing_using_RedBrush_brush_and_Square_shape"입니다. 속성에 Name "{#}"이 있기 때문에 해시는 이름의 일부가 아니므로 형식은 명명 충돌에 취약합니다. 예를 들어 형식 Drawing<Square,SpecialRedBrush> 의 데이터 계약 이름이 정확히 동일합니다.

참고하십시오