web-dev-qa-db-ja.com

WCFのDataContractのポイントは何ですか?

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();

私は何が欠けていますか?

50
Blankman

DataContractは、サービス境界の両側で理解できるタイプの単なる正式な定義です。

例のように「MyUserCollection」オブジェクトを返す場合、サービスの利用者はサービス/システムの内部を参照する必要がありますが、これはSOA明示的な境界DataContractを使用することにより、戻り値の型の構造を疎結合の方法で公開しています。

52
Guy Starbuck

注目すべきもう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が表示されることはありません(これは、たとえば、内部的にロジックを支援するプロパティですが、クライアントレベルで公開されたくない場合があります)。

26
Wagner Silveira

別の重要な用途があります。クラスとプロパティの名前を変更できます。これは、シリアル化および逆シリアル化中の便利な機能です。

[DataContract(Name="EmployeeName")]
public class Person
{
   [DataMember(Name="FullName")]
   public string Name { get; set; }

   [DataMember(Name="HomeAddress")]
   public string Address { get; set; }
}
11
Asif Mushtaq

「DataContractは、サービス境界の両側で理解できるタイプの単なる正式な定義である」と言ったポスターには同意しません。

ここのキーワードは「タイプ」です。 .NETでは、型はフィールド、プロパティ、およびメソッドを持つことができるオブジェクトです。ただし、WCFサービスでDataContractを使用してクラスを修飾すると、クラスは呼び出し元のコードに魔法のように移植されません。ロングショットではありません!呼び出しコードには、「プロキシ」クラスがあります。プロキシクラスは、データコントラクトのコンテンツを表すXMLを受け取ります。呼び出しコードはプロキシクラスを介してこれらのXML値を受け取ることができますが、notは呼び出しコードにdatacontractで飾るクラスの内部へのアクセスを許可します。

「marc_s」に回答する場合:

「ネットワークの両端に.NETがあれば、それで問題ありません。Javaクライアントがサービスを呼び出している場合はどうでしょうか。DataContractsにデータを入れると、その情報はWSDL/XSDメタデータであり、.NET以外のクライアントでも使用できます。」

間違っていると思います。これを試してみましょう:

  1. クラスのDataContract属性とメンバーのDataMemberを持つクラスと、このタイプを返すメソッドを備えたWCFプロジェクトのデフォルト例を使用します。
  2. それをビルドしてwsdlを表示します。 xsdにはCompositeType定義が含まれています。 OK。
  3. ここで、DataContractおよびDataMemberのすべての属性を削除しましょう。
  4. それをビルドしてwsdlを表示します。 xsdにはまだComposityType定義が含まれています! (ステップ2と4の間でファイルに違いがないことを示すSCMソフトを使用すると、より明確になります)

だからJavaクライアントはDataContractとDataMemberなしでこれを管理すべきです!私は間違っているのですか?

2
WolveFred

おそらくあまり使用されませんが、[DataContract]を使用してプライベート変数を渡すことができます。 [DataContract]属性が使用されていない場合、DataContractSerializerは公開されている型のみをシリアル化/逆シリアル化します。

[DataContract]
public class SampleClass
{    
    [DataMember]
    private int MyPrivateProperty { get; set; }
}

(注:プロキシを生成する場合、プライベートメンバーはパブリックとして公開されます)

0
thewpfguy