Názvy kontraktu dat

Někdy klient a služba nesdílely stejné typy. Stále se můžou vzájemně předávat data, pokud jsou kontrakty dat na obou stranách ekvivalentní. Ekvivalence kontraktů dat je založená na názvech datových kontraktů a členů, a proto je k těmto názvům k dispozici mechanismus mapování typů a členů. Toto téma vysvětluje pravidla pro pojmenování kontraktů dat a také výchozí chování infrastruktury WCF (Windows Communication Foundation) při vytváření názvů.

Základní pravidla

Mezi základní pravidla týkající se pojmenování kontraktů dat patří:

  • Plně kvalifikovaný název kontraktu dat se skládá z oboru názvů a názvu.

  • Členové dat mají pouze názvy, ale žádné obory názvů.

  • Při zpracování kontraktů dat se u infrastruktury WCF rozlišují velká a malá písmena na obory názvů i názvy kontraktů dat a datových členů.

Obory názvů kontraktů dat

Obor názvů kontraktu dat má formu identifikátoru URI (Uniform Resource Identifier). Identifikátor URI může být absolutní nebo relativní. Ve výchozím nastavení jsou datové kontrakty pro určitý typ přiřazeny oboru názvů, který pochází z oboru názvů CLR (Common Language Runtime) daného typu.

Ve výchozím nastavení se všechny dané obory názvů CLR (ve formátu Clr.Namespace) mapují na obor názvů http://schemas.datacontract.org/2004/07/Clr.Namespace. Pokud chcete toto výchozí nastavení přepsat, použijte ContractNamespaceAttribute atribut na celý modul nebo sestavení. Alternativně, chcete-li řídit obor názvů datového kontraktu pro každý typ, nastavte Namespace vlastnost DataContractAttribute.

Poznámka:

Obor http://schemas.microsoft.com/2003/10/Serialization názvů je vyhrazený a nelze ho použít jako obor názvů kontraktu dat.

Poznámka:

Výchozí obor názvů nelze přepsat v typech datových kontraktů, které obsahují delegate deklarace.

Názvy kontraktu dat

Výchozí název datového kontraktu pro daný typ je název tohoto typu. Chcete-li přepsat výchozí, nastavte Name vlastnost DataContractAttribute na alternativní název. Speciální pravidla pro obecné typy jsou popsána v části "Názvy kontraktů dat pro obecné typy" dále v tomto tématu.

Názvy datových členů

Výchozí název datového člena pro dané pole nebo vlastnost je název tohoto pole nebo vlastnosti. Chcete-li přepsat výchozí hodnotu, nastavte Name vlastnost DataMemberAttribute na alternativní hodnotu.

Příklady

Následující příklad ukazuje, jak můžete přepsat výchozí chování pojmenování kontraktů dat a datových členů.

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

Názvy kontraktů dat pro obecné typy

Existují zvláštní pravidla pro určení názvů kontraktů dat pro obecné typy. Tato pravidla pomáhají zabránit kolizím názvů kontraktů dat mezi dvěma uzavřenými obecnými typy stejného obecného typu.

Ve výchozím nastavení je název datového kontraktu pro obecný typ název typu následovaný řetězcem "Of" a názvy kontraktů dat obecných parametrů, následované hodnotou hash vypočítanou pomocí oborů názvů kontraktů dat obecných parametrů. Hodnota hash je výsledkem matematické funkce, která funguje jako "otisk prstu", která jedinečně identifikuje část dat. Pokud jsou všechny obecné parametry primitivní typy, hodnota hash se vynechá.

Podívejte se například na typy v následujícím příkladu.

[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

V tomto příkladu má typ Drawing<Square,RegularRedBrush> název datového kontraktu "DrawingOfSquareRedBrush5HWGAU6h", kde "5HWGAU6h" je hodnota hash oborů názvů "urn:shapes" a "urn:default". Typ Drawing<Square,SpecialRedBrush> má název kontraktu dat "DrawingOfSquareRedBrushjpB5LgQ_S", kde "jpB5LgQ_S" je hodnota hash oborů názvů "urn:shapes" a "urn:special". Všimněte si, že pokud se hodnota hash nepoužívá, jsou tyto dva názvy identické, a proto dojde ke kolizi názvu.

Přizpůsobení názvů kontraktů dat pro obecné typy

Někdy jsou názvy kontraktů dat vygenerované pro obecné typy, jak je popsáno výše, nepřijatelné. Můžete například předem vědět, že nedojde ke kolizím názvů a možná budete chtít hodnotu hash odebrat. V tomto případě můžete vlastnost použít DataContractAttribute.Name k určení jiného způsobu generování názvů. Čísla ve složených závorkách uvnitř Name vlastnosti můžete použít k odkazování na názvy kontraktů dat obecných parametrů. (0 odkazuje na první parametr, 1 odkazuje na druhý atd.) Pomocí znaménka čísla (#) uvnitř složených závorek můžete odkazovat na hodnotu hash. Každý z těchto odkazů můžete použít vícekrát nebo ne.

Například předchozí obecný Drawing typ mohl být deklarován, jak je znázorněno v následujícím příkladu.

[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

V tomto případě má typ Drawing<Square,RegularRedBrush> název datového kontraktu "Drawing_using_RedBrush_brush_and_Square_shape". Všimněte si, že protože vlastnost Name obsahuje {#}, hodnota hash není součástí názvu, a proto je typ náchylný ke kolizím názvů. Například typ Drawing<Square,SpecialRedBrush> by měl přesně stejný název kontraktu dat.

Viz také