0

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);
...
4

1 に答える 1

2

この問題は JSon.Net バージョン 5.0r2 のバグであり、5.0r3 に更新すると修正され、実際に 5.0r3 リリースの唯一の理由でした。

于 2013-04-24T14:07:17.870 に答える