WCFサービスがあります。
通常の操作では、サーバーが何らかの処理を行って、コールバックを介して、入力されたXactTaskInオブジェクトをクライアントに返します。これで問題ありません。
私の問題は、returnData変数を設定済みのXactExceptionに設定して、コールバック経由でクライアントにXactTaskInを返そうとすると、次の例外がスローされることです。
例外-「データコントラクト名「XactException:http://schemas.datacontract.org/2004/07/」のタイプ「XactException」は必要ありません。DataContractResolverの使用を検討するか、既知のタイプのリストに静的に不明なタイプを追加してください-たとえば、KnownTypeAttribute属性を使用するか、DataContractSerializerに渡される既知のタイプのリストに追加します。 (System.Runtime.Serialization.SerializationException)例外メッセージ=「データコントラクト名「XactException:http://schemas.datacontract.org/2004/07/」のタイプ「XactException」は必要ありません。DataContractResolverの使用を検討するか、既知のタイプのリストに静的に知られていないタイプ-たとえば、KnownTypeAttribute属性を使用するか、DataContractSerializerに渡された既知のタイプのリストに追加することにより。 "、Exception Type =" System.Runtime.Serialization.SerializationException "
これがXactTaskInクラスです
[DataContract]
public class XactTaskIn
{
[DataMember]
public DateTime timeOut;
[DataMember]
public DateTime timeIn;
[DataMember]
public string name;
[DataMember]
public string responseTo;
[DataMember]
public String moduleFromName;
[DataMember]
public String moduleFromType;
[DataMember]
public String methodFromName;
[DataMember]
public object[] originalInputs;
[DataMember]
public String returnMethodToCall;
[DataMember]
public String returnModuleToCall;
[DataMember]
public object returnData;
public XactTaskIn(DateTime timeOut, DateTime timeIn, string name, string responseTo, String moduleFromName, String moduleFromType, String methodFromName, object[] originalInputs, String returnMethodToCall, String returnModuleToCall, object returnData)
{
this.timeOut = timeOut;
this.timeIn = timeIn;
this.name = name;
this.responseTo = responseTo;
this.moduleFromName = moduleFromName;
this.moduleFromType = moduleFromType;
this.methodFromName = methodFromName;
this.originalInputs = originalInputs;
this.returnMethodToCall = returnMethodToCall;
this.returnModuleToCall = returnModuleToCall;
this.returnData = returnData;
}
}
XactExceptionクラスは次のとおりです。
[DataContract]
public class XactException
{
[DataMember]
string message;
public XactException(string message)
{
this.message = message;
// Add implementation.
}
}
更新:
ダニエルからのコメントが私を助けてくれました。
サーバーはクライアントにコールバックを送信しているように見えますが、クライアントは次の例外をスローしています。
- キャッチ:「メッセージをデシリアライズしようとしてフォーマッタが例外をスローしました:パラメータをデシリアライズしようとしてエラーが発生しました http://tempuri.org/:taskIn 。InnerExceptionメッセージは 'Error in line 1ポジション960。要素 'http://schemas.datacontract.org/2004/07/:returnData'には、名前 'http://schemas.datacontract.org/2004/07/:XactExceptionにマップされる型からのデータが含まれます。 '。デシリアライザーは、この名前にマップする型を認識しません。DataContractResolverの使用を検討するか、既知の型のリストに' XactException 'に対応する型を追加します(たとえば、KnownTypeAttribute属性を使用するか、 DataContractSerializerに渡される既知のタイプのリスト。 '詳細については、InnerExceptionを参照してください。 " (System.ServiceModel.Dispatcher.NetDispatcherFaultException)Exception Message = "フォーマッターは、メッセージのデシリアライズを試行中に例外をスローしました:パラメーターのデシリアライズ中にエラーが発生しました http://tempuri.org/:taskIn =。InnerExceptionメッセージは「行1の位置960のエラー」でした。要素「http://schemas.datacontract.org/2004/07/:returnData」には、「http:// schemas」という名前にマップされる型のデータが含まれています。 datacontract.org/2004/07/:XactException '。デシリアライザーは、この名前にマッピングされるタイプを認識しません。DataContractResolverの使用を検討するか、「XactException」に対応するタイプを既知のタイプのリストに追加します。 KnownTypeAttribute属性を使用するか、DataContractSerializerに渡される既知のタイプのリストに追加します。詳細については、InnerExceptionを参照してください。」、Exception Type =「System.ServiceModel.Dispatcher.NetDispatcherFaultException」
あなたのクラスで
[DataContract]
public class XactTaskIn
オブジェクトを返すプロパティがあります:
[DataMember]
public object[] originalInputs;
[DataMember]
public object returnData;
WCFは、すべてのタイプが何であるかを(WSDLを介して)クライアントに伝えることができるように、どのタイプが存在する可能性があるかを事前に知る必要があります。非ネイティブ型(int、string、DateTimeなどではないもの)については、次のように、これらのオブジェクトプロパティに返される可能性のあるすべての型に対して[KnownType]属性を追加する必要があります。
[KnownType(typeof(XactException))]
[KnownType(typeof(...))]
[KnownType(typeof(...))]
[DataContract]
public class XactTaskIn
このようにして、WCFがサービスのWSDLを構築するときに、データ型のリストにXactExceptionを追加することを認識し、シリアライザーもそれらのクラスを検索することを認識します。
サイドノート;クライアントがSrvUtil、サービスリファレンスを使用して構築された場合、または何らかの方法でWSDLから生成された場合、[KnownType]属性を追加した後にクライアントを再構築する必要があります。
クライアントは、XactExceptionではなくXactTaskInを予期しています。
XactTaskInを変更して、クライアントに例外オブジェクトを渡すことができるようにする必要があります。
例外datacontractを削除し、XactException型をデータメンバーとしてXactTaskInクラスに追加します
データが変更されると、シリアライゼーション例外が発生します。たとえば、フィールド名をawesomeString
からawesomeSTring
に変更するとシリアル化が中断されるなど、些細なことです。これは、新しいデータを古いデータに対して検証できなくなったためです。これに対する修正は、サーバー/クライアントが期待している古いバージョンを使用することです。