cholisky
cholisky

Reputation: 175

parsing nested (I think) JSON

I've been trying to parse this JSON string. I'm using JSON.NET and a snippet of the JSON, my classes and basic function calls follow:

{"status":"ok","apirate":"0","people":{
"Mike":{"id":"Mike","rating":"0.80","questions":"100"},
"Donald":{"id":"Donald","rating":"0.7","questions":"9"},
"Tony":{"id":"Tony","rating":"0.22","questions":"2"},
"Penelope":{"id":"Penelope","rating":"0.006","questions":"6"},
"Sarah":{"id":"Sarah","rating":"0.79","questions":"20"},
"Thomas":{"id":"Thomas","rating":"0.12","questions":"25"},
"Gail":{"id":"Gail","rating":"0.44","questions":"35"}}}

The classes I'm using as storage objects:

     public class Folks
    {
        public Folks()
        {
        }
        public String status;
        public String message; //optional
        public int apirate;
        public PeopleDetails[] people;
    }

      public class PeopleDetails 
    {
        public PeopleDetails ()
        {
        }
        public String id;
        public double rating;
        public int questions;
    }

And finally, what I'm doing in the code:

    Folks test = new Folks();
    test = JsonConvert.DeserializeObject<Folks>(myRequest.GetResponse());

Status and API rate are coming through fine, message doesn't exist because there's no error and my PeopleDetails array is making an exception. (EDIT: throwing a JsonSerializationException because the type requires a JSON array to deserialize correctly.) I've tried putting another class/object between the two I've pasted here and I've tried different collections, and so on.

So... since this is my first time working with this (smart, pick the complex stuff the first time) can anybody point me towards a solution?

Thanks in advance.

Upvotes: 0

Views: 103

Answers (1)

esskar
esskar

Reputation: 10940

Well, first, your given JSON is incorrect, there is a { missing in the penelope record.

so the correct JSON would be

{"status":"ok","apirate":"0","people":{
"Mike":{"id":"Mike","rating":"0.80","questions":"100"},
"Donald":{"id":"Donald","rating":"0.7","questions":"9"},
"Tony":{"id":"Tony","rating":"0.22","questions":"2"},
"Penelope":{"id":"Penelope","rating":"0.006","questions":"6"},
"Sarah":{"id":"Sarah","rating":"0.79","questions":"20"},
"Thomas":{"id":"Thomas","rating":"0.12","questions":"25"},
"Gail":{"id":"Gail","rating":"0.44","questions":"35"}}}

Then, if you have a look at the structur, you may not that people is not a list but a dictionary, with the name as the key.

So, here is a working test

    [TestMethod]
    public void Test()
    {
        var json = "{\"status\":\"ok\",\"apirate\":\"0\",\"people\":{\n\"Mike\":{\"id\":\"Mike\",\"rating\":\"0.80\",\"questions\":\"100\"},\n\"Donald\":{\"id\":\"Donald\",\"rating\":\"0.7\",\"questions\":\"9\"},\n\"Tony\":{\"id\":\"Tony\",\"rating\":\"0.22\",\"questions\":\"2\"},\n\"Penelope\":{\"id\":\"Penelope\",\"rating\":\"0.006\",\"questions\":\"6\"},\n\"Sarah\":{\"id\":\"Sarah\",\"rating\":\"0.79\",\"questions\":\"20\"},\n\"Thomas\":{\"id\":\"Thomas\",\"rating\":\"0.12\",\"questions\":\"25\"},\n\"Gail\":{\"id\":\"Gail\",\"rating\":\"0.44\",\"questions\":\"35\"}}}";
        var folks = JsonConvert.DeserializeObject<Folks>(json);

        Assert.AreEqual("ok", folks.Status);
    }

    public class Folks
    {
        public Folks()
        {
            this.People = new Dictionary<string, PeopleDetails>();
        }

        [JsonProperty("status")]
        public string Status { get; set; }

        [JsonProperty("message")]
        public string Message { get; set; }

        [JsonProperty("apirate")]
        public int Apirate { get; set; }

        [JsonProperty("people")]
        public Dictionary<string, PeopleDetails> People { get; set; }
    }

    public class PeopleDetails
    {
        [JsonProperty("id")]
        public string Id { get; set; }

        [JsonProperty("rating")]
        public decimal Rating { get; set; }

        [JsonProperty("questions")]
        public int Questions { get; set; }
    }

Upvotes: 1

Related Questions