I got this Json:
{
"CountriesAndCities": [
{
"CountryId": 2,
"CountryName": "Chile",
"CountryISOA3": "CHL",
"Cities": [
{
"CityId": 26,
"CityName": "Gran Santiago",
"Country": null
},
{
"CityId": 27,
"CityName": "Gran Concepción",
"Country": null
}
]
}
]
}
As you can see, it's a lists of objects, and those objects have another list nested.
I've got these models:
public class City
{
public int CityId { get; set; }
public string CityName { get; set; }
public Country Country { get; set; }
}
public class Country
{
public int CountryId { get; set; }
public string CountryName { get; set; }
public string CountryISOA3 { get; set; }
public ICollection<City> Cities { get; set; }
}
Right now, this does the trick:
public ICollection<Country> Countries { get; set; }
public RegionViewModel()
{
// Pidiendo las ciudades al backend.
S3EWebApi webApi = new S3EWebApi();
HttpResponseMessage response = webApi.Get("/api/Benefits/GetCountriesAndCities");
string jsonResponseString = response.Content.ReadAsStringAsync().Result;
JObject jsonResponse = JsonConvert.DeserializeObject<JObject>(jsonResponseString);
string countriesAndCitiesJSon = jsonResponse["CountriesAndCities"].ToString();
Countries = JsonConvert.DeserializeObject<List<Country>>(countriesAndCitiesJSon);
}
But I don't know, I think that's way too far from elegant. Is there a better approach to it? Thanks. :)
Generally speaking you should never need to deserialize twice. The simplest solution is to make a class to represent the outermost part of the JSON and then deserialize into that as shown in @Alex Wiese's answer.
If you want to deserialize without a root class then you can use the ToObject<T>()
method after you have deserialized into the JObject
.
JObject jsonResponse = JsonConvert.DeserializeObject<JObject>(jsonResponseString);
Countries = jsonResponse["CountriesAndCities"].ToObject<List<Country>>();
Make a wrapper class for the response.
public class CountriesAndCitiesResponse
{
public List<Country> CountriesAndCities { get; set; }
}
Then use it like so:
public RegionViewModel()
{
// Pidiendo las ciudades al backend.
S3EWebApi webApi = new S3EWebApi();
HttpResponseMessage response = webApi.Get("/api/Benefits/GetCountriesAndCities");
string jsonResponseString = response.Content.ReadAsStringAsync().Result;
CountriesAndCitiesResponse response = JsonConvert.DeserializeObject<CountriesAndCitiesResponse>(jsonResponseString);
Countries = response.CountriesAndCities;
}
Also you should re-think calling an async
method in a constructor (it could lead to deadlocks). You might consider having the call in an async Task Load()
method instead and calling that after calling the constructor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With