質問
System.Object 型 (WSDL の xs:anyType) のパラメーターを持つメソッドを定義するサービス コントラクトがあります。このパラメータで単純な型だけでなく複雑な型も渡せるようにしたいと考えています。単純型は正常に動作しますが、WSDL で定義されている複合型を渡そうとすると、次のエラーが発生します。
要素 'http://tempuri.org/:value' には ' のデータが含まれていますhttp://schemas.datacontract.org/2004/07/MyNamespace:MyClass' データ契約。デシリアライザーは、このコントラクトにマップされる型についての情報を持ちません。たとえば、KnownTypeAttribute 属性を使用するか、DataContractSerializer に渡される既知の型のリストにそれを追加することによって、「MyClass」に対応する型を既知の型のリストに追加します。
すでに WSDL に含まれているため、既知の型として追加しても役に立ちません。「xs:anyType」パラメータを介して複合型のオブジェクトを渡すにはどうすればよいですか?
より詳しい情報:
NetDataContract を使用する場合はこれが機能すると思いますが、クライアントが Silverlight であるため使用できません。
xs:anyType を明示的に拡張する複合型への参照は見たことがありますが、それを行う WSDL を WCF に生成させる方法がわかりません。また、それが役に立つかどうかもわかりません。
ありがとう
解決 3
ServiceKnownType 属性を使用してこの問題を解決しました。複合型をサービス契約のサービスの既知の型として追加するだけで、エラーは解消されます。前回試したときになぜこれがうまくいかなかったのかわかりません。
WSDL には何の影響もないようなので、シリアル化されたストリームには、私の型を使用してオブジェクトを逆シリアル化できることをデシリアライザーに伝える何らかの違いがあるのではないかと思います。
他のヒント
NetDataContractSerializer には型情報が含まれているため、NetDataContract は機能します。
KnownType 属性は、DataContractSerializer にメッセージを逆シリアル化する方法を指示します。これは実装固有であるため、公的契約によって定義されている以上の情報であり、WSDL には属しません。
デシリアライザーは適切な型を識別してインスタンスを作成する必要があるため、古いデータ型を渡すことはできません。
既知の型を DataContract にハードコーディングするのではなく、実行時に派生できる場合があります。見てみましょう ここ サンプル用です。
これがお役に立てば幸いです。私の同僚がこのコードを使用して複雑なデータ型を送信しているのを見ましたが、私にとってこれは非常に簡単です。これは、basicHttpBinding で使用され、MOSS BDC や基本バインディングを使用する他のアプリケーションでも非常にうまく機能します。
- ジェネリック クラスに基づいてデータ コントラクトを作成する
情報を送信する必要がある場合はデータ コントラクトを使用します
[DataContract(名前空間 = "http://Service.DataContracts"、name =" servicedatacontractbase ")] Public Class ServicedAcontract {
public ServiceDataContract() { } public ServiceDataContract(TValueType Value) { this.m_objValue = Value; } private TValueType m_objValue; [DataMember(IsRequired = true, Name = "Value", Order = 1)] public TValueType Value { get { return m_objValue; } set { m_objValue = value; } }
}
複雑なデータ型を返す WCF 関数で必要な場合には、このデータ コントラクトを使用します。例えば:
public ServiceDataContract<string[]> GetStrings()
{
string[] temp = new string[10];
return new ServiceDataContract<string[]>(temp);
}
アップデート:ServiceDataContract は TValueType を使用するジェネリック クラスです。HTML のレンダリングに問題があるため、表示されません。
データ コントラクト サロゲートを使用して、ドット ネット固有のタイプまたは相互運用不可能なタイプのサポートされていないオブジェクトをマップしてみてください。見る MSDN
現時点では、別のデータ コントラクト タイプまたは単純なタイプをラップできる新しいデータ コントラクト タイプを作成することで、この問題を回避しました。Object 型を渡す代わりに、このラッパー クラスを渡します。これは問題なく機能しますが、元の問題に対する解決策があるかどうか知りたいと思っています。
ServiceKnownType 属性を追加して、渡そうとしている型を指定しようとしましたが、同じエラーが発生します。 また、データ コントラクトに KnownType 属性を追加してみました (データ コントラクトと同じ型だったので、これは愚かに思えました)。コンパイル時に追加しても役に立たない場合は、実行時に追加しても役に立たないと思います。
別の複合型を拡張する場合は、その基本型に KnownType 属性を追加するとよいでしょう。しかし、私の基本型はオブジェクトであるため、これを行う方法がわかりません。
サロゲートに関しては、コントラクトが定義されていない型をラップするために使用されているようです。ただし、私の場合は契約を定義しています。