WCFで複合型を渡す標準化された方法は何ですか?
-
03-07-2019 - |
質問
私はWCFの初心者であり、現在TCP WCFサービスを開発しています。パラメーターの受け渡しを正しく理解しているかどうかわからないので、コメントして標準化された方法を提供することをお勧めします。
明確にするために、単一のメソッドを持ち、単一のクラスを公開する外部.Net dllに依存する、テスト目的の小さなサービスを開発しました。 サービス契約コード
[ServiceContract]
public interface IMyService
{
[OperationContract]
int Test1(actionType at, calculationType ct, action a);
[OperationContract]
int Test2(DataSeries s);
}
actionType
、 calculationType
、 action
は、外部dll内で宣言された列挙型です
DataSeries
はdll内で宣言されたクラスです。
dllの DataSeries
クラスの元の定義は、 [Serializable]
のみでマークされ、そのメンバーには [DataMember]
はありません。
クライアント側とサーバー側で3番目のdllを使用しています。驚いたのは、DataSeriesクラスに [DataContract]
を配置せず、 [EnumMember]を使用せずに、
列挙型内、 [DataMember]
クラス内。
では何が起きているのですか?
別の実験:
クライアント側からサードパーティを削除し、サービスをそのまま使用する
vs2008が列挙型と DataSeries
クラスを生成し、適切な属性でマークすることを発見しましたか?
[System.CodeDom.Compiler.GeneratedCodeAttribute ("System.Runtime.Serialization", "3.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="actionType", Namespace="http://schemas.datacontract.org/2004/07/DBInterface")]
public enum actionType : int {
[System.Runtime.Serialization.EnumMemberAttribute()]
All = 0,
[System.Runtime.Serialization.EnumMemberAttribute()]
Buy = 1,
[System.Runtime.Serialization.EnumMemberAttribute()]
Sell = 2,
}
解決
DataContract 、 DataMember および EnumMember 属性は、 DataContractSerializer (通常 basicHttpBinding または wsHttpBinding )。 TCPバインディングでエンドポイントを公開している場合( netTcpBinding ) SerializableAttribute のみが必要です。 DataContractSerializerを使用すると、SerializableAttributeをクラスにしか追加できず、すべてのフィールドが自動的にシリアル化されることに注意してください。
次のことをお勧めします。サービスを相互運用する場合は、basicHttpBindingを使用し、DataContract属性とDataMember属性でクラスをマークします。クライアントが.NETアプリケーションの場合、netTcpBindingを使用し、SerializableAttributeでクラスをマークします。
この投稿を比較して比較することもできます。異なるバインディング。
他のヒント
ただし、DataContractなどを使用せずに 属性、クライアント側を見つけました 正常に動作しています
はい、それは本当です-使用するデータ型が[DataContract]でマークされていない場合、WCFはデフォルトのSOAPシリアライザーを使用しようとし、パブリック(すべてのパブリックプロパティ)のすべてをシリアル化します。
それは動作します-しかし、それはあなたが望む/期待するものではないかもしれません-だから私は2番目のダリンの意見だろう-常にあなたのタイプで明示的な[DataContract]属性を使用してください。自分自身(または、後でコードを保守する必要がある他のプログラマー)に対して意図を明確にすればするほど、より良い結果が得られます。これらの「マジックトリック」舞台裏で起こることは時々混乱を引き起こす傾向があります-あなたはそれらに頼りすぎないの方が良いでしょう
マーク
したがって、私にとっては[DataContract] sを使用し、単一のパラメーターを渡し、データコントラクトを返します。
これにより、既存のクライアントを壊すことなく、データコントラクトに新しいオプションの属性を使用してデータコントラクトを拡張できるため、柔軟性が向上します。
Enumsデータ連絡先も作成します。なぜなら、何も壊さずに列挙を拡張して同じことができ、名前空間を制御できるからです。
[DataContract(Namespace = "http://namespace.mydomain.com/2009/05", Name = "ReferenceTypeData")]
public enum GenderEnum
{
[EnumMember()]
Unknown = 0,
[EnumMember()]
Male = 1,
[EnumMember()]
Female = 2
}
その後、サービス契約をマークする必要があります
[ServiceKnownType(typeof(GenderEnum))]
public interface IServiceContract
{
....
}