JSon.Net序列化收益率收益率的结果

时间:2013-04-15 15:49:23

标签: c# json json.net ienumerable yield-return

我正在尝试使用json和JSon.Net库将一些数据返回到web服务。我的一个函数是迭代器方法,它使用yield return列出数据。当我尝试序列化此返回值时,我收到无效的操作异常

我正在使用 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 ]

迭代器方法的签名是:

public IEnumerable<dynamic> FunctionName() { ... }

截至目前,我通过检查对此函数的调用并在返回值上调用ToList来实现临时解决方案。序列化很好,但它是一种丑陋的解决方案,因为我需要有一个特殊的情况(以及我可能添加的任何其他迭代器方法)。我的猜测是,这与IEnumerable没有被枚举有关。

我可以让Json.Net序列化我的迭代器函数的结果,还是我总是需要这样的特殊情况?如果需要更多信息或源代码,请告诉我,我会发布。

更多信息:我使用的是.Net framework 4.0版,我正在使用Json.Net版本5.0r2

迭代器方法的简要源代码

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

1 个答案:

答案 0 :(得分:2)

此问题是JSon.Net版本5.0r2的错误,更新到5.0r3将解决此问题,实际上是5.0r3版本的唯一原因。