クライアントとサービスが同じ型を共有しない場合があります。 両方の側でデータ コントラクトが同等である限り、データは引き続き相互に渡すことができます。 データ コントラクトの等価性 はデータ コントラクト名とデータ メンバー名に基づいているため、型とメンバーをそれらの名前にマップするためのメカニズムが提供されます。 このトピックでは、データ コントラクトに名前を付ける規則と、名前を作成するときの Windows Communication Foundation (WCF) インフラストラクチャの既定の動作について説明します。
基本ルール
データ コントラクトの名前付けに関する基本的な規則は次のとおりです。
完全修飾されたデータ コントラクト名は、名前空間と名前で構成されています。
データ メンバーには名前のみが含まれますが、名前空間はありません。
データ契約を処理する場合、WCFのインフラストラクチャは、名前空間やデータ契約、データメンバーの名前について大文字と小文字を区別します。
データ コントラクト名前空間
データ コントラクト名前空間は、Uniform Resource Identifier (URI) の形式になります。 URI には、絶対または相対のいずれかを指定できます。 既定では、特定の型のデータ コントラクトには、その型の共通言語ランタイム (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
ジェネリック型のデータ コントラクト名
ジェネリック型のデータ コントラクト名を決定するための特別な規則が存在します。 これらの規則は、同じジェネリック型の 2 つの閉じたジェネリック間のデータ コントラクト名の競合を回避するのに役立ちます。
既定では、ジェネリック型のデータ コントラクト名は型の名前、文字列 "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" 名前空間のハッシュです。 ハッシュが使用されていない場合、2 つの名前は同じであるため、名前の競合が発生することに注意してください。
ジェネリック型のデータ コントラクト名のカスタマイズ
前に説明したように、ジェネリック型に対して生成されたデータ コントラクト名が受け入れられない場合があります。 たとえば、名前の競合に陥らず、ハッシュを削除することが必要な場合があることを事前に把握している場合があります。 この場合、 DataContractAttribute.Name プロパティを使用して、名前を生成する別の方法を指定できます。 Name
プロパティの中かっこ内に数字を指定して、ジェネリック パラメーターのデータ コントラクト名を参照できます (0 は最初のパラメーターを参照し、1 は 2 番目のパラメーターを参照します。など)。ハッシュを参照するには、中かっこ内の数字 (#) 記号を使用できます。 これらの参照は何度でも、または一度も使用しないことも可能です。
たとえば、上記のジェネリック 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>
型のデータ コントラクト名はまったく同じになります。