22

オブジェクトを予期し、リフレクションを使用してそのプロパティを取得するWCFサービスメソッドがあります。

クライアント側では、匿名型のオブジェクトを作成します

var obj = new {FirstName="John", LastName="Doe"}

それをメソッドに渡します。例外が発生します:

Type '<>f__AnonymousType0`2[System.String,System.String]' cannot be serialized. 
Consider marking it with the DataContractAttribute attribute, and marking all 
of its members you want serialized with the DataMemberAttribute attribute.  
See the Microsoft .NET Framework documentation for other supported types.

明示的に宣言された型やプロパティが実際にはないため、型またはそのメンバーをシリアル化属性でマークすることはできません。その問題を克服する方法はありますか?

4

6 に答える 6

20

WCFで匿名型を使用できないこと示唆する答えは間違っています。

デフォルトDataContractSerializerを使用してチャネルでタイプをシリアル化する場合、はい、答えは正しいです。これは、DataContractSerializerが次のシナリオをサポートしているためです。

  1. 属性を使用してシリアル化されたタイプSerializable
  2. XMLシリアル化を使用してシリアル化されたタイプ
  3. 属性を使用してシリアル化されたタイプDataContract
  4. Plain-Old-C#-Object(POCO)シリアル化

それぞれ、次の理由で匿名タイプで失敗します。

  1. 匿名タイプに属性を適用することはできません。
  2. XMLシリアル化には、デフォルトのパラメーターなしのコンストラクターが必要ですが、匿名型にはありません。
  3. 1と同じ。
  4. 2と同じ。

ただしDataContractSerializer、 WCFでメッセージをシリアル化するためにを使用する必要はありません。自分でシリアル化を実行するために使用できるカスタムメッセージフォーマッタを作成できます。

リクエストの結果として送信するタイプが匿名タイプの場合、問題が発生します。結果が返されると、名前空間内に明確な名前が付けられ(.NETの意味ではなく、SOAの意味で)、その具象型から匿名型へのマッピングを処理する必要があります。 。ただし、実際の匿名タイプやコードでの構築方法(少なくとも動的な方法)にアクセスできないため、オブジェクトとして渡された場合は、オブジェクトとして渡す以外に選択肢はありません。誰もが動的(それ自体は悪い習慣ではありませんが、この場合はこれらの制限を回避するためにそうです)や例によるキャストなどの悪い習慣を使用する必要があるため、それは一種の価値がありません。

したがって、最終的には、匿名タイプをシリアル化してネットワーク経由で送信することは確かに可能ですが、通常、必要な作業は価値がありません。

于 2010-02-21T20:27:02.627 に答える
19

これをしないでください。

それは賢くしようとする試みです。しないでください。必要なデータ型を宣言して使用するだけです。より大まかに定義されたデータ型が必要な場合は、ある種のKey-Valueマッピングを使用してください。

これを永久に処理できるものを書くのに5分かかります。このような手法を使用すると、将来のある時点でデバッグに何時間もかかることになります。

于 2010-02-28T05:06:36.207 に答える
4

次のように、オブジェクトをJSON文字列にシリアル化し、WCFを介して送信できます。

//in WCF Server
dynamic mysentclass = new { FirstName = "John", LastName = "Doe" };
string jsonstring = JsonConvert.SerializeObject(mysentclass, Newtonsoft.Json.Formatting.Indented);
//send the string through WCF

//in WCF client
dynamic myreceivedclass = JsonConvert.DeserializeObject<dynamic>(jsonstring);
MessageBox.Show(myreceivedclass.FirstName.ToString() + " " + myreceivedclass.LastName.ToString());

この例では、Json.Netを使用しています。これは次の場所で取得できます。

http://www.nuget.org/packages/Newtonsoft.Json/

System.Web.Script.Serialization.JavaScriptSerializer(System.Web.Extensions.dll内)を使用することもできます。これは、Json.Netほど強力ではありませんが、単純なオブジェクトには十分です。

于 2013-10-18T13:02:51.813 に答える
2

いいえ、ありません。メソッドから匿名型のオブジェクトを返すためのトリックとテクニックはありますが、WCFを介してそれらを送信することはできません。

WCFは、実際には.NETメソッドを呼び出すだけではないため、送信される具体的なタイプをすべて知っている必要があります。代わりに、メッセージ呼び出しはシリアル化されたメッセージに変換されるため、WCF呼び出しを介して渡される「もの」はすべてシリアル化可能である必要があります(例外はありません)。

于 2010-02-21T19:38:15.363 に答える
1

あなたはすでに答えを持っています。それはできません。

実際、プログラムのあるメソッドから別のメソッドに匿名型のインスタンスを渡すことはできません。あなたは確かにプログラム間でそれらを渡すことはできません。

于 2010-02-21T19:37:14.443 に答える
0

前に述べたように、オブジェクトは逆シリアル化可能である必要があるため、事前に構造を定義する必要があります。ただし、継承を使用してそれらを定義することで、苦痛を軽減することができます。WCFはKnownType属性を提供して、サービス操作が基本クラスのオブジェクトを受け取り、それを派生クラスのオブジェクトに逆シリアル化できるようにします。したがって、すべてのシナリオを処理できるサービス操作は1つ(またはいくつか)しかありません。

于 2010-02-28T05:03:32.830 に答える