Поделиться через


Имена контрактов данных

Иногда клиент и служба поддерживают разные типы. При этом они все равно могут передавать данные друг другу при условии, что контракты данных эквивалентны на обеих сторонах. Эквивалентность контрактов данных основана на именах контракта данных и члена данных, следовательно, система предоставляет механизм для сопоставления типов и членов с этими именами. В этом разделе поясняются правила именования контрактов данных и описывается поведение по умолчанию инфраструктуры Windows Communication Foundation (WCF) при создании имен.

Основные правила

Ниже приведены основные правила именования контрактов данных:

  • Полное имя контракта данных состоит из пространства имен и имени.

  • Члены данных имеют только имена, но не имеют пространств имен.

  • При обработке контрактов данных инфраструктура WCF учитывает регистр пространства имен и имен контрактов данных и членов данных.

Пространства имен контракта данных

Пространство имен контракта данных принимает форму универсального кода ресурса (URI). URI может быть как абсолютным, так и относительным. По умолчанию контрактам данных определенного типа данных присваивается пространство имен из пространства имен среды CLR этого типа.

По умолчанию любое пространство имен среды CLR (в формате Clr.Namespace) сопоставляется с пространством имен "http://schemas.datacontract.org/2004/07/Clr.Namespace". Для переопределения данной настройки по умолчанию необходимо применить атрибут ContractNamespaceAttribute ко всему модулю или всей сборке. Кроме того, для того чтобы управлять пространством имен контракта данных для каждого типа, необходимо задать свойство Namespace атрибута DataContractAttribute.

ms731045.note(ru-ru,VS.100).gifПримечание
Пространство имен "https://schemas.microsoft.com/2003/10/Serialization" зарезервировано, следовательно, его невозможно использовать в качестве пространства имен контракта данных.

ms731045.note(ru-ru,VS.100).gifПримечание
Нельзя переопределять заданное по умолчанию пространство имен в типах контрактов данных, содержащих объявления delegate.

Имена контрактов данных

Имя контракта данных по умолчанию для данного типа является именем этого типа. Для переопределения данной настройки по умолчанию необходимо задать свойству Name атрибута DataContractAttribute альтернативное имя. Специальные правила для универсальных типов описаны в части "Имена контрактов данных для универсальных типов" данного раздела (см. ниже).

Имена членов данных

Имя члена данных по умолчанию для указанного поля или свойства является именем этого поля или свойства. Для переопределения данной настройки по умолчанию необходимо задать свойству Name атрибута DataMemberAttribute альтернативное значение.

Примеры

В следующем примере показано, как переопределить заданный по умолчанию принцип именования контрактов данных и членов данных.

' 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
// 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.
    }
}

Имена контрактов данных для универсальных типов

Имена контрактов данных для универсальных типов определяются по специальным правилам. Эти правила позволяют избежать конфликтов имен контрактов данных, когда речь идет о двух закрытых универсальных шаблонах одного универсального типа.

По умолчанию именем контракта данных для универсального типа является имя этого типа и строки "Of", за которыми следуют имена контрактов данных универсальных параметров и хэш, вычисляемый с помощью пространств имен контрактов данных универсальных параметров. Хэш — это результат математической функции, действующей как "отпечаток", который однозначно определяет блок данных. Когда все универсальные параметры являются типами-примитивами, хэш не используется.

Например, см. типы в следующем примере.

<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
[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.
}

В данном примере тип Drawing<Square,RegularRedBrush> имеет имя контракта данных "DrawingOfSquareRedBrush5HWGAU6h", где "5HWGAU6h" — это хэш пространств имен "urn:shapes" и "urn:default". В данном примере тип Drawing<Square,SpecialRedBrush> имеет имя контракта данных DrawingOfSquareRedBrushjpB5LgQ_S", где "jpB5LgQ_S" – это хэш пространств имен "urn:shapes" и "urn:special". Обратите внимание, что идентичность двух имен в случае, когда не используется хэш, приводит к конфликту имен.

Настройка имен контрактов данных для универсальных типов

Иногда имена контрактов данных, созданные для универсальных типов ранее описанным способом, недопустимы. Например, вы, возможно, заранее знаете, что конфликта имен не произойдет, и хотите удалить хэш. В этом случае можно использовать свойство Name атрибута DataContractAttribute, чтобы указать другой способ создания имен. Вы можете использовать числа в фигурных скобках внутри свойства Name для ссылки на имена контрактов данных универсальных параметров. (0 относится к первому параметру, 1 — ко второму, и т. д.) Для ссылки на хэш можно использовать знак номера (#) в фигурных скобках. Каждую из этих ссылок можно использовать несколько раз или не использовать совсем.

Например, приведенный выше универсальный тип Drawing мог бы быть объявлен так, как показано в примере ниже.

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

В данном случае тип Drawing<Square,RegularRedBrush> имеет имя контракта данных "Drawing_using_RedBrush_brush_and_Square_shape". Обратите внимание, что так как в свойстве Name имеется знак "{#}", хэш не является частью имени, и, следовательно, могут возникнуть конфликты имен данного типа; например, тип Drawing<Square,SpecialRedBrush> имеет точно такое же имя контракта данных.

См. также

Справочник

DataContractAttribute
DataMemberAttribute
ContractNamespaceAttribute

Основные понятия

Использование контрактов данных
Эквивалентность контрактов данных
Имена контрактов данных
Управление версиями контракта данных