データ コントラクトは、交換するデータを抽象的に記述するサービスとクライアントの間の正式な契約です。 つまり、通信するには、クライアントとサービスが同じ型を共有する必要はなく、同じデータ コントラクトのみが共有されます。 データ コントラクトは、各パラメーターまたは戻り値の型に対して、交換するシリアル化 (XML に変換) されるデータを正確に定義します。
データ コントラクトの基本
Windows Communication Foundation (WCF) は、既定でデータ コントラクト シリアライザーと呼ばれるシリアル化エンジンを使用して、データのシリアル化と逆シリアル化 (XML との間での変換) を行います。 整数や文字列などのすべての .NET Framework プリミティブ型、および DateTime や XmlElementなどのプリミティブとして扱われる特定の型は、他の準備なしでシリアル化でき、既定のデータ コントラクトがあると見なされます。 多くの .NET Framework 型には、既存のデータ コントラクトもあります。 シリアル化可能な型の完全な一覧については、「 データ コントラクト シリアライザーでサポートされる型」を参照してください。
作成する新しい複合型には、シリアル化可能にするためにデータ コントラクトが定義されている必要があります。 既定では、 DataContractSerializer はデータ コントラクトを推論し、公開されているすべての型をシリアル化します。 型のすべてのパブリック読み取り/書き込みプロパティとフィールドがシリアル化されます。 IgnoreDataMemberAttributeを使用して、シリアル化からメンバーをオプトアウトできます。 DataContractAttribute属性とDataMemberAttribute属性を使用して、データ コントラクトを明示的に作成することもできます。 これは通常、 DataContractAttribute 属性を型に適用することによって行われます。 この属性は、クラス、構造体、および列挙型に適用できます。 DataMemberAttribute属性は、データ コントラクト型の各メンバーに適用して、データ メンバーであることを示す必要があります。つまり、シリアル化する必要があります。 詳細については、「 シリアル化可能な型」を参照してください。
例
次の例は、 ServiceContractAttribute 属性と OperationContractAttribute 属性が明示的に適用されているサービス コントラクト (インターフェイス) を示しています。 この例では、プリミティブ型ではデータ コントラクトは必要ありませんが、複合型はデータ コントラクトを必要としないことを示しています。
[ServiceContract]
public interface ISampleInterface
{
// No data contract is required since both the parameter
// and return types are primitive types.
[OperationContract]
double SquareRoot(int root);
// No Data Contract required because both parameter and return
// types are marked with the SerializableAttribute attribute.
[OperationContract]
System.Drawing.Bitmap GetPicture(System.Uri pictureUri);
// The MyTypes.PurchaseOrder is a complex type, and thus
// requires a data contract.
[OperationContract]
bool ApprovePurchaseOrder(MyTypes.PurchaseOrder po);
}
<ServiceContract()> _
Public Interface ISampleInterface
' No data contract is required since both the parameter and return
' types are both primitive types.
<OperationContract()> _
Function SquareRoot(ByVal root As Integer) As Double
' No Data Contract required because both parameter and return
' types are marked with the SerializableAttribute attribute.
<OperationContract()> _
Function GetPicture(ByVal pictureUri As System.Uri) As System.Drawing.Bitmap
' The MyTypes.PurchaseOrder is a complex type, and thus
' requires a data contract.
<OperationContract()> _
Function ApprovePurchaseOrder(ByVal po As MyTypes.PurchaseOrder) As Boolean
End Interface
次の例では、クラスとそのメンバーにMyTypes.PurchaseOrder
属性とDataContractAttribute属性を適用して、DataMemberAttribute型のデータ コントラクトを作成する方法を示します。
namespace MyTypes
{
[DataContract]
public class PurchaseOrder
{
private int poId_value;
// Apply the DataMemberAttribute to the property.
[DataMember]
public int PurchaseOrderId
{
get { return poId_value; }
set { poId_value = value; }
}
}
}
Namespace MyTypes
<System.Runtime.Serialization.DataContractAttribute()> _
Public Class PurchaseOrder
Private poId_value As Integer
' Apply the DataMemberAttribute to the property.
<DataMember()> _
Public Property PurchaseOrderId() As Integer
Get
Return poId_value
End Get
Set
poId_value = value
End Set
End Property
End Class
End Namespace
注記
次のメモでは、データ コントラクトの作成時に考慮すべき項目を示します。
IgnoreDataMemberAttribute属性は、マークされていない型で使用する場合にのみ適用されます。 これには、 DataContractAttribute、 SerializableAttribute、 CollectionDataContractAttribute、または EnumMemberAttribute のいずれかの属性でマークされていない型、または他の方法 ( IXmlSerializable など) によってシリアル化可能としてマークされている型が含まれます。
DataMemberAttribute属性は、フィールドとプロパティに適用できます。
メンバーのアクセシビリティ レベル (内部、プライベート、保護、またはパブリック) は、データ コントラクトに影響を与えるものではありません。
静的メンバーに適用される場合、 DataMemberAttribute 属性は無視されます。
シリアル化中に、シリアル化するプロパティの値を取得するために、プロパティ データ メンバーのプロパティ取得コードが呼び出されます。
逆シリアル化中に、初期化されていないオブジェクトが最初に作成され、型でコンストラクターが呼び出されることはありません。 その後、すべてのデータ メンバーが逆シリアル化されます。
逆シリアル化中に、プロパティ セット コードが呼び出され、プロパティ データ メンバーが逆シリアル化される値にプロパティを設定します。
データ コントラクトを有効にするには、すべてのデータ メンバーをシリアル化できる必要があります。 シリアル化可能な型の完全な一覧については、「 データ コントラクト シリアライザーでサポートされる型」を参照してください。
ジェネリック型は、非ジェネリック型とまったく同じ方法で処理されます。 ジェネリック パラメーターには特別な要件はありません。 たとえば、次の種類を考えてみましょう。
[DataContract]
public class MyGenericType1<T>
{
// Code not shown.
}
<DataContract()> _
Public Class MyGenericType1(Of T)
' Code not shown.
End Class
ジェネリック型パラメーター (T
) に使用される型がシリアル化可能かどうかに関係なく、この型はシリアル化できます。 すべてのデータ メンバーをシリアル化できる必要があるため、次のコードに示すように、ジェネリック型パラメーターもシリアル化可能な場合にのみ、次の型をシリアル化できます。
[DataContract]
public class MyGenericType2<T>
{
[DataMember]
T theData;
}
<DataContract()> _
Public Class MyGenericType2(Of T)
<DataMember()> _
Dim theData As T
End Class
データ コントラクトを定義する WCF サービスの完全なコード サンプルについては、 基本データ コントラクト のサンプルを参照してください。