json と JSon.Net ライブラリを使用して、Web サービスにデータを返そうとしています。私の関数の 1 つは、yield return を使用してデータをリストする iterator メソッドです。この戻り値をシリアル化しようとすると、無効な操作の例外が発生します
string jsonEncoded = JsonConvert.SerializeObject(ret, Formatting.Indented);
戻り値をシリアル化するために使用
しています。
例外の完全なスタック トレースは次のとおりです。
System.InvalidOperationException: This operation is only valid on generic types.
at System.RuntimeType.GetGenericTypeDefinition()
at Newtonsoft.Json.Serialization.JsonArrayContract..ctor(Type underlyingType) in c:\Temp\Json\Working\Newtonsoft.Json\Src\Newtonsoft.Json\Serialization\JsonArrayContract.cs:line 148
at Newtonsoft.Json.Serialization.DefaultContractResolver.CreateArrayContract(Type objectType) in c:\Temp\Json\Working\Newtonsoft.Json\Src\Newtonsoft.Json\Serialization\DefaultContractResolver.cs:line 686
at Newtonsoft.Json.Serialization.DefaultContractResolver.CreateContract(Type objectType) in c:\Temp\Json\Working\Newtonsoft.Json\Src\Newtonsoft.Json\Serialization\DefaultContractResolver.cs:line 800
at Newtonsoft.Json.Serialization.DefaultContractResolver.ResolveContract(Type type) in c:\Temp\Json\Working\Newtonsoft.Json\Src\Newtonsoft.Json\Serialization\DefaultContractResolver.cs:line 232
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.GetContractSafe(Object value) in c:\Temp\Json\Working\Newtonsoft.Json\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalWriter.cs:line 83
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType) in c:\Temp\Json\Working\Newtonsoft.Json\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalWriter.cs:line 67
at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType) in c:\Temp\Json\Working\Newtonsoft.Json\Src\Newtonsoft.Json\JsonSerializer.cs:line 753
at Newtonsoft.Json.JsonSerializer.Serialize(JsonWriter jsonWriter, Object value, Type objectType) in c:\Temp\Json\Working\Newtonsoft.Json\Src\Newtonsoft.Json\JsonSerializer.cs:line 668
at Newtonsoft.Json.JsonConvert.SerializeObject(Object value, Type type, Formatting formatting, JsonSerializerSettings settings) in c:\Temp\Json\Working\Newtonsoft.Json\Src\Newtonsoft.Json\JsonConvert.cs:line 921
at Newtonsoft.Json.JsonConvert.SerializeObject(Object value, Formatting formatting, JsonSerializerSettings settings) in c:\Temp\Json\Working\Newtonsoft.Json\Src\Newtonsoft.Json\JsonConvert.cs:line 893
at Newtonsoft.Json.JsonConvert.SerializeObject(Object value, Formatting formatting) in c:\Temp\Json\Working\Newtonsoft.Json\Src\Newtonsoft.Json\JsonConvert.cs:line 837
at AladdinWeb.Handlers.AladdinHandler.ProcessRequest(HttpContext context) in C:\Users\mehrlich\Projects\AladdinWeb\AladdinWeb\Server\Handlers\AladdinHandler.cs:line 85 [ 15/04/2013 11:24:24.68135 ]
iterator メソッドのシグネチャは次のとおりです。
public IEnumerable<dynamic> FunctionName() { ... }
今のところ、この関数の呼び出しをチェックしToList
て戻り値を呼び出すことで、一時的な解決策を用意しています。これは問題なくシリアル化されますが、特別なケース (および追加する可能性のあるその他の反復子メソッド) が必要なため、一種の醜いソリューションです。私の推測では、これは IEnumerable が列挙されていないことに関係していると思います。
Json.Net にイテレータ関数の結果をシリアル化させることはできますか?それとも、このような特別なケースが常に必要ですか? さらに情報やソース コードが必要な場合はお知らせください。投稿します。
詳細情報: .Net フレームワーク バージョン 4.0 を使用しており、Json.Net バージョン 5.0r2 を使用しています。
Iterator メソッドの要約ソース コード
public IEnumerable<dynamic> FunctionName()
{
var methodList = typeof(Targets).GetMethods();
foreach (var m in methodList)
{
dynamic info = new ExpandoObject();
info.Name = m.Name;
info.Parameters = from param in m.GetParameters()
select param.Name;
yield return info;
}
}
メソッド呼び出しのソースコード
...
object ret = null;
if (q == "FunctionName")
{
ret = FunctionName(); // This causes an exception to be thrown later
// ret = FunctionName().ToList(); // This does NOT throw an exception later
}
else
{
ret = DoOtherStuff(q, request);
}
// Serialize the result to JSON
// This line throws the exception
string jsonEncoded = JsonConvert.SerializeObject(ret, Formatting.Indented);
...