有時候客戶端和服務不會共用相同的類型。 只要數據合約在兩端都相等,它們仍然可以互相傳遞數據。 數據合約等價是以數據合約 和數據成員名稱為基礎,因此會提供一個機制,將類型和成員對應至這些名稱。 本主題說明在建立名稱時命名數據合約的規則,以及 Windows Communication Foundation (WCF) 基礎結構的預設行為。
基本規則
命名資料合約的基本規則包括:
完整數據合約名稱是由命名空間和名稱所組成。
數據成員只有名稱,但沒有命名空間。
當處理資料合約時,WCF 基礎結構對命名空間、資料合約的名稱和資料成員是區分大小寫的。
數據合約命名空間
數據合約命名空間的格式為統一資源標識碼(URI)。 URI 可以是絕對或相對的。 根據預設,特定類型的數據合約會指派來自該類型的 Common Language Runtime (CLR) 命名空間的命名空間。
根據預設,任何指定的 CLR 命名空間 (格式為 Clr.Namespace) 會對應至命名空間 http://schemas.datacontract.org/2004/07/Clr.Namespace。 若要覆寫此預設值,請將 ContractNamespaceAttribute 屬性套用至整個模組或元件。 或者,若要控制每個型別的數據合約命名空間,請設定 Namespace 的 DataContractAttribute屬性。
備註
命名空間 http://schemas.microsoft.com/2003/10/Serialization 是保留的,不能當做數據合約命名空間使用。
備註
您無法覆寫包含 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.
}
}
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
泛型型別的數據合約名稱
特殊規則可用於判斷泛型型別的數據合約名稱。 這些規則有助於避免相同泛型類型的兩個封閉泛型之間的數據合約名稱衝突。
根據預設,泛型型別的數據合約名稱是類型的名稱,後面接著字串 「Of」,後面接著泛型參數的數據合約名稱,後面接著使用泛型參數的數據合約命名空間計算的 哈希 。 哈希是數學函式的結果,其做為可唯一識別數據片段的「指紋」。 當所有泛型參數都是基本類型時,會省略哈希。
例如,請參閱下列範例中的類型。
[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
在此範例中,此類型 Drawing<Square,RegularRedBrush> 具有數據合約名稱 「DrawingOfSquareRedBrush5HWGAU6h」,其中 「5HWGAU6h」 是 「urn:shapes」 和 “urn:default” 命名空間的哈希。 此類型 Drawing<Square,SpecialRedBrush> 具有數據合約名稱 「DrawingOfSquareRedBrushjpB5LgQ_S」,其中 「jpB5LgQ_S」 是 「urn:shapes」 和 「urn:special」 命名空間的哈希。 請注意,如果未使用哈希,則兩個名稱都相同,因此會發生名稱衝突。
自定義泛型型別的數據合約名稱
有時候,針對泛型型別所產生的數據合約名稱,如先前所述,是不可接受的。 例如,您可能事先知道您不會遇到名稱衝突,而且可能想要移除哈希。 在此情況下,您可以使用 DataContractAttribute.Name 屬性來指定產生名稱的不同方式。 您可以在 屬性內的大括弧中使用 Name 數位來參考泛型參數的數據合約名稱。 (0 是指第一個參數,1 是指第二個參數,依故。您可以在大括弧內使用數位 (#) 符號來參考哈希。 您可以多次使用這些參考資料中的每一個,或者完全不使用。
例如,上述泛型 Drawing 類型可能已宣告為 ,如下列範例所示。
[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
在此情況下,類型 Drawing<Square,RegularRedBrush> 具有資料合約名稱「Drawing_using_RedBrush_brush_and_Square_shape」。 請注意,因為 屬性中有 Name “{#}”,所以哈希不是名稱的一部分,因此類型很容易命名衝突;例如,該類型 Drawing<Square,SpecialRedBrush> 會有完全相同的數據合約名稱。