クラスの定義外のWCFシリアル化情報
-
26-10-2019 - |
質問
この簡単なシナリオを想定してください。私のクライアントにはすでに動作している.NETアプリケーションがあり、WCFを通じて何らかの機能を公開したいと考えています。そこで彼は私にアセンブリを与え、FollowIGメソッドを公開する公開クラスを連れて行きます。
OrderDetail GetOrderDetail (int orderId) // Suppose OrderDetail has {ProductId, Quantity, Amount)
今、私はOrderDetailの一部のメンバー(金額)がシリアル化されないようにしたいです。によると http://msdn.microsoft.com/en-us/library/aa738737.aspx, 、これを行う方法は、[dataContract]および[datamember]/[adianoredatamember]属性を使用します。ただし、クライアントのソースコードを変更できないため、それは私にとって選択肢ではありません。だから、タイプの定義の外で、どのメンバーをシリアル化したいかを指定する方法を探しています。このように見えるはずの何か:
[OperationContract]
[IgnoreMember(typeof(OrderDetail), "Amount" )]
OrderDetail QueryOrder(int orderId){
return OrderDetail.GetOrderDetail(orderId)
}
これには何か方法はありますか?ありがとう、ベルナベ
解決
クライアントオブジェクトをワイヤー間で送信しないでください。送信する情報のみを含むクライアントオブジェクトからDTOを作成して、代わりに送信します。
これにより、どの情報が送信されるかを正確に制御でき、オブジェクトではなくメッセージを渡すというWCFの意図に沿っています
したがって、作成します OrderDetailDto class
これをからのデータに入力します OrderDetail
クライアントコードのメソッドへの呼び出しによって返されます。飾る OrderDetailDto
とともに DataContract
と DataMember
属性(ここのクラスの名前を変更できます。これにより、WCFによって返されると名前が返されます。 OrderDetail
)
クライアントコードのすべてのオブジェクトに対してこれを繰り返し、サービス境界で基本的にDTO->クライアントオブジェクトとクライアントオブジェクトから変換するように
編集
あなたが求めたものを許可するオプションがあるかもしれません(私は1つを知っていませんが、他の誰かがそうかもしれないことを願っています)あなたのクライアントオブジェクトをDTOとして使用するとき、あなたはそれらを2つの目的で使用していることを考慮します(クライアントオブジェクト単一の責任の原則に反するメッセージ契約)、クライアント側にそれらを取得すると、それらは同じクライアント側のオブジェクトではなく、同じプロパティを持つDTOだけでなく、クライアントで動作を取得することはできませんサイドオブジェクト(少なくともサーバー側とクライアント側のライブラリを共有せずに)。
データ契約をオブジェクトにバインドすることにより、クライアントオブジェクトとデータ契約の変更を1つのこととして管理する必要があります。それらが別々の場合、DTOをネック的に変更することなく、クライアントサイドオブジェクトの変更を管理できます。
DTOを作成するのは多くの作業のように思えますが、最終的には価値があると思います。
他のヒント
目的のプロパティのみを公開し、クライアントが提供するクラスをその価値を取得するために単純に呼び出すラッパークラスを書く必要があります。
他の唯一のオプションは、それをリフレクションとシリアル化を使用して新しい動的クラスを放出することです(参照 http://msdn.microsoft.com/en-us/library/system.reflection.emit.typebuilder.aspx)、しかし、多くのラッパークラスを構築する必要がない限り、おそらく努力する価値はありません。