Lior Naar Lior Naar - 1 month ago 15
C# Question

Can't implement Iterator design pattern after JsonConvert when trying to Deserialize json

I have the following Object that matches the pattern of a JSON object i get from one REST request I send:

public class MyObject
{
public List<string> columns { get; set; }
public List<List<string>> rows { get; set; }
public DisplayValue displayValue { get; set; }
public string currency { get; set; }
public object alert { get; set; }
}

public class DisplayValue
{
public Id DisplayId { get; set; }
}

public class Id
{
public List<string> IdToName { get; set; }
}


this object match to the response I get and the next code is working with the upper implementation of MyObject (I'm using C#'s RestSharp):

var response = client.Execute(request);
result = JsonConvert.DeserializeObject<MyObject>(response.Content);


Now I would like to implement the Iterator design pattern on MyObject since MyObject.rows is the only field I actually use.

So I've changed MyObject class to the following

public class MyObject : IEnumerable<List<string>
{
public List<string> columns { get; set; }
public List<List<string>> rows { get; set; }
public DisplayValue displayValue { get; set; }
public string currency { get; set; }
public object alert { get; set; }
}


public IEnumerator<List<string>> GetEnumerator()
{
foreach (List<string> row in rows)
{
yield return row;
}
}

IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}

public class DisplayValue
{
public Id DisplayId { get; set; }
}

public class Id
{
public List<string> IdToName { get; set; }
}


But when I try to JSONConvert I get the following exception:


Cannot deserialize the current JSON object (e.g. {"name":"value"})
into type
'MyObject' because
the type requires a JSON array (e.g. [1,2,3]) to deserialize
correctly. To fix this error either change the JSON to a JSON array
(e.g. [1,2,3]) or change the deserialized type so that it is a normal
.NET type (e.g. not a primitive type like integer, not a collection
type like an array or List) that can be deserialized from a JSON
object. JsonObjectAttribute can also be added to the type to force it
to deserialize from a JSON object.


Any idea to why is this happening?

dbc dbc
Answer

The problem is that Json.NET will try to serialize any POCO that implements IEnumerable<T> for some T as a JSON array rather than a JSON object, as is documented here. Since your JSON is presumably not an array, you receive the exception you are seeing.

Since you don't want your MyObject serialized as an array, you can force Json.NET to (de)serialize it as an object instead by marking it with [JsonObject]:

[JsonObject]
public class MyObject : IEnumerable<List<string>>
{
    public List<string> columns { get; set; }
    public List<List<string>> rows { get; set; }
    public DisplayValue displayValue { get; set; }
    public string currency { get; set; }
    public object alert { get; set; }

    // Implementation of IEnumerable<List<string>>...
}

See JsonObjectAttribute force object serialization.