-1

I need to convert this type of json

{  
   "italy":[  
      {  
         "city":"rome",
         "people":100000
      },
      {  
         "city":"milan",
         "people":50000
      }
   ],
   "spain":[  
      {  
         "city":"barcelona",
         "people":100000
      },
      {  
         "city":"madrid",
         "people":2000
      }
   ]
}

into a list of this c# class

    class CityPeople
    {
        public string City { get; set; }
        public string Country { get; set; }
        public int People { get; set; }
    }

so, in this specific case i would like to have a List composed of 4 entries, 2 for italy and 2 for spain.

How can i deserialize the json into this class?

i tried to do a sandard deserialize like this but without success because the json is not a jsonarray

List<CityPeople> citiesPeople = JsonConvert.DeserializeObject<List<CityPeople>>(myJson);
Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
CaTourist
  • 711
  • 3
  • 9
  • 21
  • 5
    You should post what you've tried so far. – dcg Jun 13 '17 at 14:33
  • updated the snippet – CaTourist Jun 13 '17 at 14:39
  • Your json is an object with two properties (`italy` and `spain`) and you're trying to deserialize it as a list of cities which is not possible. – dcg Jun 13 '17 at 14:44
  • 1
    Related: https://stackoverflow.com/a/14161675/993547 – Patrick Hofman Jun 13 '17 at 14:45
  • which can be a strategy to obtain the same result? do i have to manually parse the json string? – CaTourist Jun 13 '17 at 14:46
  • You could just parse it and then get the list of cities by calling the `DeserializeObject>` on those json properties. – dcg Jun 13 '17 at 14:48
  • If you control the shape of the json, you can change it to an array of countries, with each country having a name property and an array of cities. That would map nicely to a list of country and city POCOs. Otherwise Patrick's comment - and Jon Skeet's answer he's linking to - seems like your best bet. – Yannick Meeus Jun 13 '17 at 14:51

3 Answers3

4

The simplest approach is often the best one.

Why not add a class to your project that represents exactly what the json is:

public class CityInfo
{
    public string City { get; set; }
    public int People { get; set; }
}

Then you can Deserialize into a Dictionary<string, CityInfo[]> and build your CityPeople objects like so:

List<CityPeople> cityPeople = new List<CityPeople>();
foreach(var f in JsonConvert.DeserializeObject<Dictionary<string, CityInfo[]>>(json))
{
    foreach(var i in f.Value)
    {
        cityPeople.Add(new CityPeople() {
            City = i.City,
            Country = f.Key,
            People = i.People
        });
    }
}

Working fiddle here

maccettura
  • 10,514
  • 3
  • 28
  • 35
1

I solved doing a deserialize to a Dictionary<string,CityPeople> and then converting the dictionary to a list updating the city during conversion.

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
CaTourist
  • 711
  • 3
  • 9
  • 21
1

Another approach:

        var obj = JsonConvert.DeserializeObject<JObject>(jsonText);
        IEnumerable<CityPeople> cityPeople = obj.Cast<KeyValuePair<string, JToken>>().SelectMany(kvp =>
        {
            return kvp.Value.ToObject<List<CityPeople>>().Select(c =>
            {
                c.Country = kvp.Key;
                return c;
            });
        });
BFree
  • 102,548
  • 21
  • 159
  • 201