2011-09-16 11 views
7

でオブジェクトをインスタンス化:WCF私は以下のように2つのクラスを持っているのDataContractコンストラクタ

[DataContract] 
public class Address 
{ 
    [DataMember] 
    public string Line1 
    [DataMember] 
    public string Line2 
    [DataMember] 
    public string City 
    [DataMember] 
    public string State 
    [DataMember] 
    public string Zip 
} 

[DataContract] 
public class Customer 
{ 
    public Customer() 
    { 
     CustomerAddress = new Address(); 
    } 

    [DataMember] 
    public string FirstName 
    [DataMember] 
    public string LastName 
    [DataMember] 
    public Address CustomerAddress 
} 

私はCustomerクラスを使用して、私のサービスのプロキシを生成する場合はどうなりますか?コンセプトを正しく理解すれば、Customerクラスのコンストラクタはクライアント側で呼び出されず、異なる動作をする可能性があります。

Customerクラスのコンストラクタを削除しても、AddressCustomerAddressプロパティがあり、ダムDTOオブジェクトとして動作するようにするにはどうすればよいですか?

この状況を回避するために人々が使用する一般的なガイドラインやベストプラクティスは何ですか?

答えて

6

オブジェクトをシリアル化するためにデフォルトのDataContractSerializerを使用する場合は、コンストラクタはシリアル化されず、オブジェクトがシリアル化されていない場合はクライアントによって呼び出されることはありません。

コンストラクタロジックを削除し、入れ子になったAddressクラスを持つことについての質問は、DataContractSerializerで処理されます。私はこのようなコードがある場合:

Customer c = new Customer() { 
    FirstName = "David", 
    LastName = "Hoerster", 
    CustomerAddress = new Address() { 
    Line1 = "1 Main Street", 
    City = "Smallville", 
    State = "AA", 
    Zip = "12345" 
    } 
}; 

をし、その後CustomerオブジェクトはAddress情報とともに適切にシリアライズされることをサービスメソッドからそれを返します。生成されたクライアント上のプロキシはAddressを知り、Customerオブジェクトを適切に構築するためにサービスメソッドからのストリームを逆シリアル化できます。あなたのCustomerはダミーのDTOになります。論理はなく、プロパティだけです。

Aaron Skonnard氏のMSDN articleをWCFシリアル化でチェックし、DataContractSerializerについて説明します。

0

すべてのデータコントラクトクラスをアセンブリ内で定義し、サーバープロジェクトとクライアントプロジェクトの両方をアセンブリに参照して、初期化動作を共有できるようにする方がよいでしょう。サービス参照を生成するときに、既存のデータコントラクトクラスを使用するようにコードジェネレータに指示できます。

1

あなたはクライアント(svcutilを使用するか、または「サービス参照の追加」を参照)を生成場合には、生成されたのDataContractは、次のようになります。あなたの実装の詳細は引き継がれません

[DataContract] 
public class Customer 
{ 
    // empty default constructor 
    public Customer() 
    { 
    } 

    [DataMember] 
    public string FirstName 
    [DataMember] 
    public string LastName 
    [DataMember] 
    public Address CustomerAddress 
} 

。この場合生成されるのはWSDLに入るものだけです。この場合は[DataMember]のプロパティです。

元の質問に「プロキシを生成するとどうなりますか?」と表示されます。


これは、サーバからクライアントに送信されているオブジェクトである場合は、ちょうど常にクライアントに送信する前にCustomerAddressを初期化することができます。実際に元のコードがサーバー上にある場合、そのコンストラクターが実行され、WCFはCustomerAddressをシリアル化し、基本的にはnullを送信しません(コンストラクターの後でnullに戻さない限り)。

あなたが、あなたはできる、クライアントは常にあなたのCustomerAddress送信するようにしたい場合:

  • がnullのためサーバーチェックを持って、必要に応じて
  • if(x.CustomerAddress == null) x.CustomerAddress = new Address();のようなデータメンバーマークし、クライアントが何も渡さなかった場合、サーバーはエラーを返します。[DataMember(IsRequired=true)] public Address CustomerAddress;

それ以外の場合は、生成を強制する方法はないと思いますd WCFクライアントがそのフィールドを初期化します。

関連する問題