Question

I am trying to return some data to a webservice using json and the JSon.Net library. One of my functions is an iterator method that lists data using yield return. When I try to serialize this return value, I am getting an invalid operation exception

I am using string jsonEncoded = JsonConvert.SerializeObject(ret, Formatting.Indented); to serialize the return value.

The full stack trace of the exception is:

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 ]

The signature of the iterator method is:

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

As of now, I have a temporary solution in place by checking for calls to this function and calling ToList on the return value. This serializes just fine, but it is kind of an ugly solution since I need to have a special case for it (and any other iterator methods I might add). My guess is that this has to do with the IEnumerable not being enumerated.

Can I get Json.Net to serialize the result of my iterator functions or will I always need a special case like this? Let me know if any more information or source code is needed and I will post it.

More Info: I am using the .Net framework version 4.0 and I am using Json.Net version 5.0r2

Abridged Source Code of the Iterator Method

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;
    }
}

Source Code of Method Call

...
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);
...
Was it helpful?

Solution

This issue is a bug with JSon.Net version 5.0r2, updating to 5.0r3 will fix this and in fact was the only reason for the 5.0r3 release.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top