数据协定名称

有时,客户端和服务不共享相同的类型。 它们仍然可以将数据传递给对方,只要数据协定是双方等效的。 数据协定等效性基于数据协定和数据成员名称,因此提供了一种机制用于将类型和成员映射到这些名称。 本主题说明数据协定的命名规则以及创建名称时 Windows Communication Foundation (WCF) 基础结构的默认行为。

基本规则

有关数据协定命名的基本规则包括:

  • 完全限定的数据协定名称由命名空间和名称组成。

  • 数据成员只有名称,而没有命名空间。

  • 处理数据协定时,WCF 基础结构对数据协定和数据成员的命名空间和名称区分大小写。

数据协定命名空间

数据协定命名空间采用统一资源标识符 (URI) 的形式。 URI 可以是绝对的,也可以是相对的。 默认情况下,会为特定类型的数据协定分配公共语言运行库 (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> 类型将具有完全相同的数据协定名称。

请参阅