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, und 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 beliebige 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 "https://schemas.microsoft.com/2003/10/Serialization-"Namespace wird 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.
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.
}
}
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 Generika 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(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.
}
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 Name-Eigenschaft des DataContractAttribute-Attributs 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 (null) verweist auf den ersten Parameter, 1 verweist auf den zweiten usw.) Um auf den Hash zu verweisen, können Sie ein Rautezeichen (#) in geschweiften Klammern verwenden. 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(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.
}
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
Verweis
DataContractAttribute
DataMemberAttribute
ContractNamespaceAttribute
Konzepte
Verwenden von Datenverträgen
Datenvertragsäquivalenz
Datenvertragsnamen
Datenvertragsversionsverwaltung