VS.netは、WCFプロジェクトを作成するときにテンプレートを作成します。
クラスをiService1.csファイルに追加します。
// Use a data contract as illustrated in the sample below to
// add composite types to service operations.
[DataContract]
public class CompositeType
{
bool boolValue = true;
string stringValue = "Hello ";
[DataMember]
public bool BoolValue
{
get { return boolValue; }
set { boolValue = value; }
}
[DataMember]
public string StringValue
{
get { return stringValue; }
set { stringValue = value; }
}
}
WCFサービスは任意のユーザー定義クラスを返すことができるため、なぜDataContractおよびCompositeTypeクラスを使用するのですか?
私は次のようなものを返すことができます:
[OperationContract]
MyUserCollection GetUsers();
私は何が欠けていますか?
DataContractは、サービス境界の両側で理解できるタイプの単なる正式な定義です。
例のように「MyUserCollection」オブジェクトを返す場合、サービスの利用者はサービス/システムの内部を参照する必要がありますが、これはSOA明示的な境界DataContractを使用することにより、戻り値の型の構造を疎結合の方法で公開しています。
注目すべきもう1つの興味深い点は、DataContractを使用してコードを装飾する場合、クライアントが表示できるものについて多くの制御権を持ち、サービスに送り返す必要があることです。例えば:
[DataContract]
public class SampleClass
{
[DataMember(IsRequired=true)]
public int MyRequiredProperty { get; set; }
[DataMember]
public int MyOptionalProperty { get; set; }
public int MyInternalProperty { get; set; }
}
上記の例では、データを受信するときにMyRequiredPropertyが必要であり、MyOptionalPropertyを使用できるかどうかを定義しました。また、クライアントにはMyInternalPropertyが表示されることはありません(これは、たとえば、内部的にロジックを支援するプロパティですが、クライアントレベルで公開されたくない場合があります)。
別の重要な用途があります。クラスとプロパティの名前を変更できます。これは、シリアル化および逆シリアル化中の便利な機能です。
[DataContract(Name="EmployeeName")]
public class Person
{
[DataMember(Name="FullName")]
public string Name { get; set; }
[DataMember(Name="HomeAddress")]
public string Address { get; set; }
}
「DataContractは、サービス境界の両側で理解できるタイプの単なる正式な定義である」と言ったポスターには同意しません。
ここのキーワードは「タイプ」です。 .NETでは、型はフィールド、プロパティ、およびメソッドを持つことができるオブジェクトです。ただし、WCFサービスでDataContract
を使用してクラスを修飾すると、クラスは呼び出し元のコードに魔法のように移植されません。ロングショットではありません!呼び出しコードには、「プロキシ」クラスがあります。プロキシクラスは、データコントラクトのコンテンツを表すXMLを受け取ります。呼び出しコードはプロキシクラスを介してこれらのXML値を受け取ることができますが、notは呼び出しコードにdatacontract
で飾るクラスの内部へのアクセスを許可します。
「marc_s」に回答する場合:
「ネットワークの両端に.NETがあれば、それで問題ありません。Javaクライアントがサービスを呼び出している場合はどうでしょうか。DataContractsにデータを入れると、その情報はWSDL/XSDメタデータであり、.NET以外のクライアントでも使用できます。」
間違っていると思います。これを試してみましょう:
だからJavaクライアントはDataContractとDataMemberなしでこれを管理すべきです!私は間違っているのですか?
おそらくあまり使用されませんが、[DataContract]を使用してプライベート変数を渡すことができます。 [DataContract]属性が使用されていない場合、DataContractSerializerは公開されている型のみをシリアル化/逆シリアル化します。
[DataContract]
public class SampleClass
{
[DataMember]
private int MyPrivateProperty { get; set; }
}
(注:プロキシを生成する場合、プライベートメンバーはパブリックとして公開されます)