データ コントラクト名
クライアントとサービスが同じ型を共有しないことがあります。このような場合でも、双方のデータ コントラクトが等価であれば、相互にデータを受け渡すことができます。データ コントラクトの等価性は、データ コントラクトとデータ メンバーの名前に基づいているため、型とメンバーを名前にマップするための機構が用意されています。ここでは、データ コントラクトの命名規則に加えて、名前を作成する際の Windows Communication Foundation (WCF) インフラストラクチャの既定の動作についても説明します。
基本的な規則
データ コントラクトの名前付けに関する基本的な規則は次のとおりです。
データ コントラクトの完全修飾名は、名前空間と名前から構成されます。
データ メンバーは名前のみを持ち、名前空間はありません。
データ コントラクトを処理するときに、WCF インフラストラクチャは、データ コントラクトの名前空間と名前およびデータ メンバーの名前について大文字と小文字を区別します。
データ コントラクト名前空間
データ コントラクトの名前空間は、URI (Uniform Resource Identifier) の形式を使用します。URI は、絶対 URI でも相対 URI のどちらでもかまいません。既定では、特定の型のデータ コントラクトには、その型の共通言語ランタイム (CLR: Common Language Runtime) 名前空間に基づく名前空間が割り当てられます。
既定では、任意の CLR 名前空間 (Clr.Namespace の形式) が、名前空間 "http://schemas.datacontract.org/2004/07/Clr.Namespace" にマップされます。この既定をオーバーライドするには、ContractNamespaceAttribute 属性をモジュールまたはアセンブリ全体に適用します。また、型ごとにデータ コントラクト名前空間を制御するには、DataContractAttribute の Namespace プロパティを設定します。
注 : |
---|
"https://schemas.microsoft.com/2003/10/Serialization" 名前空間は予約されているため、データ コントラクトの名前空間として使用することはできません。 |
注 : |
---|
delegate 宣言を含むデータ コントラクト型では、既定の名前空間をオーバーライドすることはできません。 |
データ コントラクト名
ある型のデータ コントラクトの既定の名前は、その型の名前になります。この既定をオーバーライドするには、DataContractAttribute の Name プロパティを別の名前に設定します。ジェネリック型に関する特別な規則については、このトピックで後述される「ジェネリック型のデータ コントラクト名」で説明します。
データ メンバー名
フィールドまたはプロパティのデータ メンバーの既定の名前は、そのフィールドまたはプロパティの名前になります。この既定をオーバーライドするには、DataMemberAttribute の Name プロパティを別の値に設定します。
例
次の例では、データ コントラクトおよびデータ メンバーの既定の名前付け動作をオーバーライドする方法を示します。
' 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.
}
}
ジェネリック型のデータ コントラクト名
ジェネリック型のデータ コントラクト名を決定する場合は、特別な規則があります。これらの規則は、同じジェネリック型の 2 つのクローズ ジェネリックの間でデータ コントラクト名の競合を回避するのに役立ちます。
既定では、ジェネリック型のデータ コントラクト名は、型の名前の後に文字列 "Of"、ジェネリック パラメーターのデータ コントラクト名、ジェネリック パラメーターのデータ コントラクト名前空間を使用して計算されたハッシュが続きます。ハッシュとは、1 つのデータを一意に識別するための "指紋" として機能する、数学関数の結果です。ジェネリック パラメーターがすべてプリミティブ型の場合は、ハッシュは省略されます。
たとえば、次の例の型を見てください。
<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.
}
この例では、Drawing<Square,RegularRedBrush>
型は "DrawingOfSquareRedBrush5HWGAU6h" というデータ コントラクト名を持ちます。ここで "5HWGAU6h" は "urn:shapes" および "urn:default" 名前空間のハッシュになります。Drawing<Square,SpecialRedBrush>
型は "DrawingOfSquareRedBrushjpB5LgQ_S" というデータ コントラクト名を持ちます。ここで "jpB5LgQ_S" は "urn:shapes" および "urn:special" 名前空間のハッシュになります。ハッシュを使用しないと 2 つの名前は同一になり、名前の競合が発生することに注意してください。
ジェネリック型のデータ コントラクト名のカスタマイズ
前述のようにジェネリック型用に生成されたデータ コントラクト名を容認できない場合があります。たとえば、名前の競合が起こらないことが前もってわかっているため、ハッシュを削除するとします。この場合、DataContractAttribute 属性の Name プロパティを使用して、名前を生成する別の方法を指定できます。Name プロパティの中かっこ内に数字を指定して、ジェネリック パラメーターのデータ コントラクト名を参照できます (0 は最初のパラメーターを参照し、1 は 2 番目のパラメーターを参照します。以下同様です)。中かっこ内にシャープ記号 (#) を指定すると、ハッシュを参照できます。これらの各参照は、複数回使用しても、まったく使用しなくてもかまいません。
たとえば、前の Drawing
ジェネリック型は次の例に示すように宣言できます。
<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.
}
この場合、Drawing<Square,RegularRedBrush>
型は、"Drawing_using_RedBrush_brush_and_Square_shape" というデータ コントラクト名になります。Name プロパティに "{#}" があるため、名前にはハッシュは含まれません。したがって、この型では名前の競合が発生しやすくなります。たとえば、Drawing<Square,SpecialRedBrush>
型は、まったく同じデータ コントラクト名を持ちます。
参照
リファレンス
DataContractAttribute
DataMemberAttribute
ContractNamespaceAttribute