Udostępnij za pośrednictwem


Nazwy kontraktów danych

Czasami klient i usługa nie współużytkują tych samych typów. Nadal mogą przekazywać dane do siebie tak długo, jak kontrakty danych są równoważne po obu stronach. Równoważność kontraktu danych opiera się na nazwach kontraktów danych i składowych danych, dlatego mechanizm jest dostarczany do mapowania typów i elementów członkowskich na te nazwy. W tym temacie opisano reguły nazewnictwa kontraktów danych oraz domyślne zachowanie infrastruktury programu Windows Communication Foundation (WCF) podczas tworzenia nazw.

Podstawowe reguły

Podstawowe reguły dotyczące kontraktów danych nazewnictwa obejmują:

  • W pełni kwalifikowana nazwa kontraktu danych składa się z przestrzeni nazw i nazwy.

  • Składowe danych mają tylko nazwy, ale nie mają przestrzeni nazw.

  • Podczas przetwarzania kontraktów danych infrastruktura WCF uwzględnia wielkość liter zarówno przestrzeni nazw, jak i nazwy kontraktów danych i składowych danych.

Przestrzenie nazw kontraktu danych

Przestrzeń nazw kontraktu danych ma postać identyfikatora URI (Uniform Resource Identifier). Identyfikator URI może być bezwzględny lub względny. Domyślnie kontrakty danych dla określonego typu są przypisywane przestrzeni nazw pochodzącej z przestrzeni nazw środowiska uruchomieniowego języka wspólnego (CLR) tego typu.

Domyślnie dowolna przestrzeń nazw CLR (w formacie Clr.Namespace) jest mapowana na przestrzeń nazw http://schemas.datacontract.org/2004/07/Clr.Namespace. Aby zastąpić tę wartość domyślną ContractNamespaceAttribute , zastosuj atrybut do całego modułu lub zestawu. Alternatywnie, aby kontrolować przestrzeń nazw kontraktu danych dla każdego typu, ustaw Namespace właściwość DataContractAttribute.

Uwaga

http://schemas.microsoft.com/2003/10/Serialization Przestrzeń nazw jest zarezerwowana i nie może być używana jako przestrzeń nazw kontraktu danych.

Uwaga

Nie można zastąpić domyślnej przestrzeni nazw w typach kontraktów danych zawierających delegate deklaracje.

Nazwy kontraktów danych

Domyślna nazwa kontraktu danych dla danego typu to nazwa tego typu. Aby zastąpić wartość domyślną, ustaw Name właściwość elementu DataContractAttribute na alternatywną nazwę. W dalszej części tego tematu opisano specjalne reguły dla typów ogólnych w sekcji "Nazwy kontraktów danych dla typów ogólnych".

Nazwy elementów członkowskich danych

Domyślną nazwą elementu członkowskiego danych dla danego pola lub właściwości jest nazwa tego pola lub właściwości. Aby zastąpić wartość domyślną, ustaw Name właściwość właściwości DataMemberAttribute na wartość alternatywną.

Przykłady

W poniższym przykładzie pokazano, jak można zastąpić domyślne zachowanie nazewnictwa kontraktów danych i składowych danych.

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

Nazwy kontraktów danych dla typów ogólnych

Istnieją specjalne reguły określania nazw kontraktów danych dla typów ogólnych. Te reguły pomagają uniknąć kolizji nazw kontraktów danych między dwoma zamkniętymi rodzajami tego samego typu ogólnego.

Domyślnie nazwa kontraktu danych dla typu ogólnego to nazwa typu, a następnie ciąg "Of", a następnie nazwy kontraktów danych parametrów ogólnych, a następnie skrót obliczony przy użyciu przestrzeni nazw kontraktu danych parametrów ogólnych. Skrót jest wynikiem funkcji matematycznej, która działa jako "odcisk palca", który jednoznacznie identyfikuje fragment danych. Gdy wszystkie parametry ogólne są typami pierwotnymi, skrót zostanie pominięty.

Na przykład zobacz typy w poniższym przykładzie.

[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

W tym przykładzie typ Drawing<Square,RegularRedBrush> ma nazwę kontraktu danych "DrawingOfSquareRedBrush5HWGAU6h", gdzie "5HWGAU6h" jest skrótem przestrzeni nazw "urn:shapes" i "urn:default". Typ Drawing<Square,SpecialRedBrush> ma nazwę kontraktu danych "DrawingOfSquareRedBrushjpB5LgQ_S", gdzie "jpB5LgQ_S" jest skrótem przestrzeni nazw "urn:shapes" i przestrzeniami nazw "urn:special". Należy pamiętać, że jeśli skrót nie jest używany, dwie nazwy są identyczne, a tym samym występuje kolizja nazw.

Dostosowywanie nazw kontraktów danych dla typów ogólnych

Czasami nazwy kontraktów danych generowane dla typów ogólnych, zgodnie z wcześniejszym opisem, są niedopuszczalne. Na przykład możesz wiedzieć z wyprzedzeniem, że nie wystąpią kolizje nazw i może chcieć usunąć skrót. W takim przypadku można użyć DataContractAttribute.Name właściwości , aby określić inny sposób generowania nazw. W nawiasach klamrowych wewnątrz Name właściwości można używać liczb, aby odwoływać się do nazw kontraktów danych parametrów ogólnych. (0 odnosi się do pierwszego parametru, 1 odnosi się do drugiego itd.) Możesz użyć znaku liczbowego (#) wewnątrz nawiasów klamrowych, aby odwołać się do skrótu. Można użyć każdego z tych odwołań wiele razy lub w ogóle nie.

Na przykład poprzedni typ ogólny Drawing mógł zostać zadeklarowany, jak pokazano w poniższym przykładzie.

[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

W tym przypadku typ Drawing<Square,RegularRedBrush> ma nazwę kontraktu danych "Drawing_using_RedBrush_brush_and_Square_shape". Należy pamiętać, że ponieważ właściwość Name "{#}" nie jest częścią nazwy, dlatego typ jest podatny na kolizje nazewnictwa, na przykład typ Drawing<Square,SpecialRedBrush> będzie miał dokładnie taką samą nazwę kontraktu danych.

Zobacz też