データ コントラクトの使用Using Data Contracts

データ コントラクト は、サービスとクライアントの間の正式な取り決めであり、交換されるデータが抽象的に記述されています。A data contract is a formal agreement between a service and a client that abstractly describes the data to be exchanged. つまり、クライアントとサービスが通信するために必要なのは同じデータ コントラクトだけで、同じ型を共有する必要はありません。That is, to communicate, the client and the service do not have to share the same types, only the same data contracts. データ コントラクトは、パラメーターまたは戻り値の型ごとに、交換するためにシリアル化する (XML に変換する) 必要があるデータを正確に定義します。A data contract precisely defines, for each parameter or return type, what data is serialized (turned into XML) to be exchanged.

データ コントラクトの基本Data Contract Basics

Windows Communication Foundation (WCF) は、(変換して、XML から) データを逆シリアル化およびシリアル化する、既定では、データ コントラクト シリアライザーと呼ばれるシリアル化エンジンを使用します。Windows Communication Foundation (WCF) uses a serialization engine called the Data Contract Serializer by default to serialize and deserialize data (convert it to and from XML). すべて .NET Framework のプリミティブ型、整数や文字列などと特定の種類などのプリミティブとして扱われますDateTimeXmlElement、準備なしでシリアル化できるし、既定のデータ コントラクトを持つと見なされます。All .NET Framework primitive types, such as integers and strings, as well as certain types treated as primitives, such as DateTime and XmlElement, can be serialized with no other preparation and are considered as having default data contracts. 多くの .NET Framework 型は、既存のデータ コントラクトを持ちます。Many .NET Framework types also have existing data contracts. シリアル化できるすべての型の一覧については、「 データ コントラクト シリアライザーでサポートされる型」を参照してください。For a full list of serializable types, see Types Supported by the Data Contract Serializer.

新しい複合型を作成したら、シリアル化できるように、データ コントラクトを定義する必要があります。New complex types that you create must have a data contract defined for them to be serializable. 既定では、 DataContractSerializer はデータ コントラクトを推測し、公開されている型をすべてシリアル化します。By default, the DataContractSerializer infers the data contract and serializes all publicly visible types. その型の読み書き可能なパブリック プロパティおよびパブリック フィールドは、すべてシリアル化されます。All public read/write properties and fields of the type are serialized. IgnoreDataMemberAttributeを使用することにより、メンバーがシリアル化されないようにすることができます。You can opt out members from serialization by using the IgnoreDataMemberAttribute. また、 DataContractAttribute 属性および DataMemberAttribute 属性を使用して、データ コントラクトを明示的に作成することもできます。You can also explicitly create a data contract by using DataContractAttribute and DataMemberAttribute attributes. これを行うには、通常、その型に DataContractAttribute 属性を適用します。This is normally done by applying the DataContractAttribute attribute to the type. この属性は、クラス、構造体、および列挙体に適用できます。This attribute can be applied to classes, structures, and enumerations. 次に、データ コントラクト型の各メンバーに DataMemberAttribute 属性を適用して、それが データ メンバーであること、つまり、シリアル化する必要があることを示す必要があります。The DataMemberAttribute attribute must then be applied to each member of the data contract type to indicate that it is a data member, that is, it should be serialized. 詳細については、次を参照してください。シリアル化できる型します。For more information, see Serializable Types.

Example

ServiceContractAttribute 属性と OperationContractAttribute 属性が明示的に適用されたサービス コントラクト (インターフェイス) の例を次に示します。The following example shows a service contract (an interface) to which the ServiceContractAttribute and OperationContractAttribute attributes have been explicitly applied. この例は、プリミティブ型はデータ コントラクトを必要としないのに対し、複合型は必要とすることを示しています。The example shows that primitive types do not require a data contract, while a complex type does.

[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 型のデータ コントラクトが作成され、 DataContractAttributeDataMemberAttribute 属性がクラスとそのメンバーに適用されるかを示します。The following example shows how a data contract for the MyTypes.PurchaseOrder type is created by applying the DataContractAttribute and DataMemberAttribute attributes to the class and its members.

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 

メモNotes

以下に、データ コントラクトを作成する際に考慮する必要がある項目を示します。The following notes provide items to consider when creating data contracts:

  • IgnoreDataMemberAttribute 属性は、マークされていない型で使用した場合にのみ受け入れられます。The IgnoreDataMemberAttribute attribute is only honored when used with unmarked types. これには、 DataContractAttributeSerializableAttributeCollectionDataContractAttributeEnumMemberAttribute のいずれかの属性でマークされていない型、または他の方法 ( IXmlSerializableなど) でシリアル化可能としてマークされた型が含まれます。This includes types that are not marked with one of the DataContractAttribute, SerializableAttribute, CollectionDataContractAttribute, or EnumMemberAttribute attributes, or marked as serializable by any other means (such as IXmlSerializable).

  • DataMemberAttribute 属性は、フィールドおよびプロパティに適用できます。You can apply the DataMemberAttribute attribute to fields, and properties.

  • メンバーのアクセシビリティ レベル (内部、プライベート、保護、またはパブリック) は、データ コントラクトに影響しません。Member accessibility levels (internal, private, protected, or public) do not affect the data contract in any way.

  • DataMemberAttribute 属性が静的メンバーに適用されている場合は無視されます。The DataMemberAttribute attribute is ignored if it is applied to static members.

  • シリアル化中には、プロパティのデータ メンバーがシリアル化対象のプロパティの値を取得できるように、プロパティ取得コードが呼び出されます。During serialization, property-get code is called for property data members to get the value of the properties to be serialized.

  • 逆シリアル化中には、まず初期化されていないオブジェクトが、その型のコンストラクターを呼び出さずに作成されます。During deserialization, an uninitialized object is first created, without calling any constructors on the type. 次に、すべてのデータ メンバーが逆シリアル化されます。Then all data members are deserialized.

  • 逆シリアル化中には、プロパティのデータ メンバーが、プロパティを逆シリアル化されている値に設定できるように、プロパティ設定コードが呼び出されます。During deserialization, property-set code is called for property data members to set the properties to the value being deserialized.

  • データ コントラクトが有効であるためには、すべてのデータ メンバーをシリアル化できる必要があります。For a data contract to be valid, it must be possible to serialize all of its data members. シリアル化できるすべての型の一覧については、「 データ コントラクト シリアライザーでサポートされる型」を参照してください。For a full list of serializable types, see Types Supported by the Data Contract Serializer.

    ジェネリック型は、非ジェネリック型とまったく同じように処理されます。Generic types are handled in exactly the same way as non-generic types. ジェネリック パラメーターに対する特別な要件はありません。There are no special requirements for generic parameters. たとえば、次の型について考えます。For example, consider the following type.

[DataContract]
public class MyGenericType1<T>
{
    // Code not shown.
}
<DataContract()>  _
Public Class MyGenericType1(Of T)
    ' Code not shown.
End Class

この型は、ジェネリック型パラメーター (T) に使用される型をシリアル化できるかどうかに関係なくシリアル化できます。This type is serializable whether the type used for the generic type parameter (T) is serializable or not. すべてのデータ メンバーをシリアル化できる必要があるため、次の型をシリアル化できるのは、ジェネリック型パラメーターもシリアル化できる場合だけです。次のコード例を参照してください。Because it must be possible to serialize all data members, the following type is serializable only if the generic type parameter is also serializable, as shown in the following code.

[DataContract]
public class MyGenericType2<T>
{
    [DataMember]
    T theData;
}
<DataContract()>  _
Public Class MyGenericType2(Of T)
    <DataMember()>  _
    Dim theData As T
End Class 

データ コントラクトを定義する WCF サービスのコード サンプル全体については、「 基本的なデータ コントラクト 」のサンプルを参照してください。For a complete code sample of a WCF service that defines a data contract see the Basic Data Contract sample.

関連項目See also