5

私は WCF にかなり慣れていないので、MessageContract の継承を正しく機能させる方法について質問があります。私のセットアップの簡略化されたバージョンは次のとおりです-「ベース」メッセージタイプと、それを継承する別の「テスト」メッセージ。

[MessageContract]
public abstract class BaseMessage
{ }

[MessageContract]
public class TestMessage : BaseMessage
{ }

次に、ServiceContract に非同期の OperationContract を次のように定義します。

[OperationContract(AsyncPattern = true)]
IAsyncResult BeginFindRequest(BaseMessage request, AsyncCallback callback, object asyncState);

私が得ている問題は、BeginFindRequest メソッドを呼び出し、要求パラメーターの TestMessage インスタンスを渡すときに、WCF フレームワークがサービス/サーバー側で TestMessage インスタンスを BaseMessage に逆シリアル化していることです。これは抽象クラスとして定義されているため、次のエラーが発生します。

「メッセージにはデフォルトの (パラメーターなしの) コンストラクターがないため、メッセージを MessageContract タイプの BaseMessage に逆シリアル化することはできません。」

MessageContract の継承に関する限られた情報から、それは機能するはずです。

私の質問は、これを機能させるために何が欠けているかです。それとも、そのタイプ専用の ServiceContract に個別の OperationContract を定義する必要がありますか?

4

5 に答える 5

6

最後に、頭に釘を打ったこのブログ投稿を見つけました-

残念ながら、コントラクトが WCF で表現される方法は、その目的が何であるかを非常に忘れがちです。操作に送信されるメッセージと、操作から返されるメッセージを定義することです。実際には、「このデータを XML でどのように表現するか」を考える必要があります。XML は継承をサポートしていないため、コントラクトに入れるものはすべて、何らかの方法で XML にマッピングする必要があります。メッセージを定義するために使用されるデータ コントラクトは、渡したいデータの XML を生成するための単純な .NET 型付けの便利なものです。他の方法でそれらを表示すると、苦痛の世界に運命づけられます。したがって、ビジネス層でデータがどのように表現されるかではなく、渡したいデータについて考え、それに応じて DataContracts を設計してください。

http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,a3775eb1-b441-43ad-b9f1-e4aaba404235.aspx

そのため、リファクタリングして、明示的なコントラクト型を持つ追加のメソッドを提供します。これにより、すべての型チェックを削除して、サービスの実装をクリーンアップすることもできます。

助けてくれてありがとう。

于 2009-08-24T14:42:11.667 に答える
3

OK、最初の質問は、なぜ本当にメッセージ コントラクトを使用しているのかということです。本当にその必要がありますか??

通常、メッセージ コントラクトは、SOAP メッセージのレイアウトを厳密に制御する必要がある場合にのみ使用されます。たとえば、特定のヘッダーなどを必要とするレガシー システムを呼び出す必要がある場合などです。

"通常の" WCF 呼び出しでは、メッセージ コントラクトを使用する必要はほとんどありません。

を使用してサービス呼び出し (サービスのメソッド) を定義し[ServiceContract]、データ構造は として渡され[DataContract]ます。DataContract がある場合、サービスで継承/ポリモーフィズムを処理する方法について、より多くのオプションがあります (メッセージ コントラクト コンストラクトよりも多くのオプションがあります)。

マルク

于 2009-08-24T09:45:41.477 に答える
0

パラメータなしのコンストラクタを持つ具体的なクラスになるように BaseMessage を変更することは可能ですか?

このエラー メッセージは、BaseMessage 型のオブジェクトは抽象的であるため、初期化する方法がないことを示しています。

于 2009-08-24T09:26:55.537 に答える
0

このエラーは、使用できるデフォルトの空のコンストラクターが必要なだけです。ただし、marc_s; には同意します。私が取り組んできたプロジェクトでは、メッセージ コントラクトをほとんど使用したことがありません。覚えている唯一のケースは、ファイル チャンクがメッセージで渡されるファイル転送サービスの一部でした。

于 2009-08-24T09:52:56.577 に答える
0

KnownType属性で装飾[ServiceContract]してみてください。TestMessageは公開操作からは「見えない」ため、これは配管がそれを見たときにそれを処理する方法を知るのに役立ちます。

これにより、をTestMessage[DataContract]としてシリアル化できるようにする必要がある場合でも、' ' またはその他のキャストを介して複数のメッセージを異なる方法で処理する必要がある可能性があります。is a

于 2009-08-24T11:34:11.070 に答える