資料合約名稱

有時候用戶端和服務不會共用相同的類型。 只要兩邊的資料合約都相同,仍然可以相互傳遞資料。 資料合約等價依據的是資料合約與資料成員名稱,因此它提供的機制會將型別與成員對應到這些名稱。 此主題說明資料合約的命名規則,以及建立名稱時 Windows Communication Foundation (WCF) 基礎結構的預設行為。

基本規則

有關命名資料合約的基本規則包括:

  • 完整的資料合約名稱是由命名空間與名稱組成。

  • 資料成員只有名稱但是沒有命名空間。

  • 當處理資料合約時,WCF 基礎結構對命名空間及資料合約與資料成員的名稱都會區分大小寫。

資料合約命名空間

資料合約命名空間使用的格式為統一資源識別元 (URI)。 這個 URI 可為絕對或相對的。 根據預設,特定類型的資料合約會指派來自該類型之 Common Language Runtime (CLR) 命名空間的命名空間。

根據預設,任何指定的 CLR 命名空間 (使用格式為 Clr.Namespace ) 都會對應至命名空間 http://schemas.datacontract.org/2004/07/Clr.Namespace。 若要覆寫這個預設值,請將 ContractNamespaceAttribute 屬性套用至整個模組或組件。 或是控制每個類型的資料合約命名空間,設定 NamespaceDataContractAttribute 屬性。

注意

http://schemas.microsoft.com/2003/10/Serialization 命名空間會保留下來,不能當做資料合約的命名空間來使用。

注意

您無法覆寫其中包含 delegate 宣告之資料合約類型中的預設命名空間。

資料合約名稱

指定類型的資料合約預設名稱是該類型的名稱。 若要覆寫預設值,請將 NameDataContractAttribute 屬性設定為替代名稱。 泛型類型的特殊規則會在本主題稍後的「泛型類型的資料合約名稱」中描述。

資料成員名稱

指定欄位或屬性的資料成員預設名稱是該欄位或屬性的名稱。 若要覆寫預設值,請將 NameDataMemberAttribute 屬性設定為替代值。

範例

下列程式碼範例顯示如何覆寫資料合約與資料成員的預設命名行為。

// 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> 可能會擁有完全相同的資料合約名稱。

另請參閱