Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting "because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly" error when deserializing a Json object

Please help me. Where I am missing info? I need to deserialize the following JSON string.

{"results":[{"series":[{"name":"PWR_00000555","columns":["time","last"],"values":[["1970-01-01T00:00:00Z",72]]}]}]}

For this, I have defined my class:

public class Serie
{
    public Serie()
    {
        this.Points = new List<object[]>();
    }

    [JsonProperty(PropertyName = "results")]
    public string results { get; set; }

    [JsonProperty(PropertyName = "series")]
    public string sries { get; set; }


    [JsonProperty(PropertyName = "name")]
    public string Name { get; set; }

    [JsonProperty(PropertyName = "columns")]
    public string[] ColumnNames { get; set; }

    [JsonProperty(PropertyName = "values")]
    public List<object[]> Points { get; set; }

But when I try using the de-serializer, it gives an exception.

{"Cannot deserialize the current JSON object (e.g. {\"name\":\"value\"}) into type 'System.Collections.Generic.List`1[InfluxDB.Serie]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.\r\nTo 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<T>) 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.\r\nPath 'results', line 2, position 12."}

like image 659
user649459 Avatar asked Oct 30 '15 01:10

user649459


2 Answers

You are getting this error because your JSON is hierarchical while your class is essentially flat. If you use JSONLint.com to validate and reformat the JSON, you can see the structure better:

{
    "results": [
        {
            "series": [
                {
                    "name": "PWR_00000555",
                    "columns": [
                        "time",
                        "last"
                    ],
                    "values": [
                        [
                            "1970-01-01T00:00:00Z",
                            72
                        ]
                    ]
                }
            ]
        }
    ]
}

This corresponds to the following class structure (which I initially generated using json2csharp.com, then manually edited to add the [JsonProperty] attributes):

public class RootObject
{
    [JsonProperty("results")]
    public List<Result> Results { get; set; }
}

public class Result
{
    [JsonProperty("series")]
    public List<Series> Series { get; set; }
}

public class Series
{
    [JsonProperty("name")]
    public string Name { get; set; }
    [JsonProperty("columns")]
    public List<string> ColumnNames { get; set; }
    [JsonProperty("values")]
    public List<List<object>> Points { get; set; }
}

You can deserialize your JSON into the above class structure like this:

var root = JsonConvert.DeserializeObject<RootObject>(jsonString);

Fiddle: https://dotnetfiddle.net/50Z64s

like image 143
Brian Rogers Avatar answered Sep 28 '22 11:09

Brian Rogers


If you're willing to sacrifice IntelliSense and compile time type safety, then you can simply deserialize the JSON into a dynamic object:

dynamic parsed = JsonConvert.DeserializeObject(jsonString);
PrintAllNames(parsed);

//...

private void PrintAllNames(dynamic obj)
{
    foreach(var result in obj.results)
        foreach(var item in result.series)
            Console.WriteLine(item.name);
}
like image 21
Matias Cicero Avatar answered Sep 28 '22 12:09

Matias Cicero