3

次の単純なシナリオを想定してください。私のクライアントは既に動作している .net アプリケーションを持っており、WCF を介していくつかの機能を公開したいと考えています。それで彼は、次のメソッドを公開する public クラスを含むアセンブリを私にくれました。

OrderDetail GetOrderDetail (int orderId) // Suppose OrderDetail has {ProductId, Quantity, Amount)

ここで、OrderDetail (Amount) の一部のメンバーをシリアル化しないようにします。http://msdn.microsoft.com/en-us/library/aa738737.aspxによると、これを行う方法は [DataContract] および [DataMember]/[IgnoreDataMember] 属性を使用することです。ただし、クライアントのソース コードを変更することはできないため、それは私にとって選択肢ではありません。そのため、型の定義の外で、シリアル化するメンバーを指定する方法を探しています。次のようになります。

    [OperationContract]
    [IgnoreMember(typeof(OrderDetail), "Amount" )]
    OrderDetail QueryOrder(int orderId){
          return OrderDetail.GetOrderDetail(orderId)  
    }

これに何か方法はありますか?ありがとう、ベルナベ

4

2 に答える 2

4

クライアントオブジェクトをネットワーク経由で送信しないでください。送信したい情報のみを含むクライアントオブジェクトからDTOを作成し、代わりにそれを送信してください。

これにより、送信される情報を正確に制御でき、オブジェクトではなくメッセージを渡すという WCF の意図に沿ったものになります。

したがって、 を作成し、これに、クライアント コードのメソッドへの呼び出しによって返されたOrderDetailDto classからのデータを入力します。との属性で The をOrderDetail装飾します (ここでクラスの名前を変更して、WCF によって返されるときに名前で返されるようにすることができます) 。OrderDetailDtoDataContractDataMemberOrderDetail

クライアント コード内のすべてのオブジェクトに対してこれを繰り返し、サービス境界で基本的に DTO -> クライアント オブジェクトおよびクライアント オブジェクト -> DTO から変換します。

編集

あなたが要求したことを許可するオプションがあるかもしれませんが(私はそれを知りませんが、うまくいけば他の誰かがそうするかもしれません)、クライアントオブジェクトをDTOとして使用する場合、それらを2つの目的で使用していることを考慮してください(クライアントオブジェクトこれは単一責任の原則に反しており、クライアント側でそれらを取得すると、同じクライアント側オブジェクトではなく、同じプロパティを持つ DTO だけになり、クライアントで動作を取得できなくなります。サイド オブジェクト (少なくとも、サーバー サイドとクライアント サイドでライブラリを共有しない限り)。

データ コントラクトをオブジェクトにバインドすることで、クライアント オブジェクトとデータ コントラクトへの変更を 1 つのものとして管理しなければならなくなります。それらが分離されている場合、DTO を必ずしも変更することなく、クライアント側オブジェクトへの変更を管理できます。別の方法で入力するだけです。

DTO を作成するのは大変な作業のように思えますが、最終的にはそれだけの価値があると思います。

于 2011-06-10T14:53:38.417 に答える
1

必要なプロパティのみを公開し、クライアントが提供したクラスを呼び出して値を取得するだけのラッパー クラスを作成する必要があります。

他の唯一のオプションは、リフレクションを使用して新しい動的クラスを発行し、それをシリアル化することです ( http://msdn.microsoft.com/en-us/library/system.reflection.emit.typebuilder.aspxを参照) 。多くのラッパー クラスを構築する必要がない限り、努力する価値はあります。

于 2011-06-10T14:57:47.667 に答える