Datenvertragsnamen

Zuweilen verfügen Client und Dienst nicht über dieselben Typen. Sie können jedoch Daten austauschen, wenn die Datenverträge auf beiden Seiten gleich sind. Datenvertragsäquivalenz basiert auf Datenvertrags- und Datenmembernamen. Daher wird ein Mechanismus bereitgestellt, der diesen Namen Typen und Member zuordnet. In diesem Thema werden die Regeln für die Namensgebung von Datenverträgen sowie das Standardverhalten der Windows Communication Foundation (WCF)-Infrastruktur bei der Namenserstellung erläutert.

Grundregeln

Zu den Grundregeln bei der Namensvergabe von Datenverträgen gehören:

  • Ein vollständig qualifizierter Datenvertragsname besteht aus einem Namespace und einem Namen.

  • Datenelemente verfügen nur über Namen, aber nicht über Namespaces.

  • Bei der Verarbeitung von Datenverträgen unterscheidet die WCF-Infrastruktur bei den Namespaces, den Namen der Datenverträge und den Datenelementen zwischen Groß- und Kleinschreibung.

Datenvertragsnamespaces

Ein Datenvertragsnamespace nimmt die Form eines URI (Uniform Resource Identifiers) an. Der URI kann entweder absolut oder relativ sein. Standardmäßig wird Datenverträgen eines bestimmten Typs ein Namespace zugeordnet, der aus dem Namespace der CLR (Common Language Runtime) desselben Typs resultiert.

Standardmäßig wird jeder angegebene CLR-Namespace (im Format Clr.Namespace) dem Namespace http://schemas.datacontract.org/2004/07/Clr.Namespace zugeordnet. Um diesen Standard zu überschreiben, übernehmen Sie das ContractNamespaceAttribute-Attribut für das ganze Modul oder die Assembly. Alternativ können Sie den Datenvertragsnamespace für jeden Typ kontrollieren, indem Sie die Namespace-Eigenschaft des DataContractAttribute festlegen.

Hinweis

Der http://schemas.microsoft.com/2003/10/Serialization-Namespace ist reserviert und kann nicht als Datenvertragsnamespace verwendet werden.

Hinweis

Sie können den Standardnamespace nicht in Datenvertragstypen überschreiben, die delegate-Deklarationen enthalten.

Datenvertragsnamen

Der Standardname eines Datenvertrags für einen gegebenen Typ ist der Name des Typs. Um diesen Standard zu überschreiben, legen Sie die Name-Eigenschaft auf dem DataContractAttribute auf einen alternativen Namen fest. Besondere Regeln für generische Typen werden weiter unten in diesem Thema unter "Datenvertragsnamen für generische Typen" beschrieben.

Datenelementnamen

Der Standardname eines Datenelements für ein gegebenes Feld oder eine gegebene Eigenschaft ist der Name des Felds oder der Eigenschaft. Um diesen Standard zu überschreiben, legen Sie die Name-Eigenschaft des DataMemberAttribute auf einen alternativen Wert fest.

Beispiele

Das folgende Beispiel zeigt, wie Sie das Standardbenennungsverhalten für Datenverträge und Datenelemente überschreiben können.

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

Datenvertragsnamen für generische Typen

Für die Bestimmung von Datenvertragsnamen für generische Typen existieren besondere Regeln. Diese Regeln helfen, Übereinstimmungen von Datenvertragsnamen zwischen zwei geschlossenen Generics des gleichen generischen Typs zu vermeiden.

Standardmäßig ist der Datenvertragsname eines generischen Typs der Name des Typs, gefolgt von der Zeichenfolge "Of", gefolgt von den Datenvertragsnamen der generischen Parameter, gefolgt von einem Hash und errechnet mithilfe der Datenvertragsnamespaces der generischen Parameter. Ein Hash ist das Ergebnis einer mathematischen Funktion, die als "Fingerabdruck" fungiert, der Daten eindeutig identifiziert. Wenn es sich bei allen generischen Parametern um primitive Typen handelt, wird der Hash weggelassen.

Betrachten Sie beispielsweise die Typen im folgenden Beispiel:

[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

In diesem Beispiel hat der Typ Drawing<Square,RegularRedBrush> den Datenvertragsnamen "DrawingOfSquareRedBrush5HWGAU6h", wobei "5HWGAU6h" ein Hash der Namespaces "urn:shapes" und "urn:default" ist. Der Typ Drawing<Square,SpecialRedBrush> hat den Datenvertragsnamen "DrawingOfSquareRedBrushjpB5LgQ_S", wobei "jpB5LgQ_S" ein Hash der Namespaces "urn:shapes" und "urn:special" ist. Beachten Sie, dass die beiden Namen bei Nichtverwendung des Hashes identisch sind und daher ein Namenskonflikt auftritt.

Anpassen von Datenvertragsnamen für generische Typen

Zuweilen sind die für generische Typen erstellten Datenvertragsnamen, wie zuvor beschrieben, nicht akzeptabel. Beispielsweise können Sie von vornherein wissen, dass eine Übereinstimmung der Namen ausgeschlossen ist, und möchten daher den Hash entfernen. In diesem Fall können Sie die DataContractAttribute.Name-Eigenschaft nutzen, um eine andere Art der Erstellung der Namen festzulegen. Sie können Zahlen in geschweiften Klammern innerhalb der Name-Eigenschaft nutzen, um auf Datenvertragsnamen von generischen Parametern zu verweisen. (0 bezieht sich auf den ersten Parameter, 1 auf den zweiten usw.) Sie können ein Zahlenzeichen (#) in geschweiften Klammern verwenden, um auf den Hash zu verweisen. Sie können jeden dieser Verweise mehrmals oder gar nicht verwenden.

Beispielsweise könnte der vorangehende allgemeine Drawing-Typ deklariert worden sein, wie im folgenden Beispiel gezeigt:

[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

In diesem Fall hat der Typ Drawing<Square,RegularRedBrush> den Datenvertragsnamen "Drawing_using_RedBrush_brush_and_Square_shape". Beachten Sie, dass der Hash aufgrund des "{#}" in der Name-Eigenschaft nicht Teil des Namens ist und der Typ somit einer Benennungsübereinstimmung unterliegen kann. Beispielsweise hätte der Typ Drawing<Square,SpecialRedBrush> den gleichen Datenvertragsnamen.

Siehe auch