Reputation: 5189
So in my app I have to get a JSON string. It can be a City or a List of Cities.
In the City class I have this:
public class City
{
public string id { get; set; }
public string country { get; set; }
public string region { get; set; }
public string city { get; set; }
public string latitude { get; set; }
public string longitude { get; set; }
public string comment { get; set; }
public bool wasThereAnError { get; set; }
public class CityResponse
{
public string status { get; set; }
public string message { get; set; }
//public City result { get; set; }
public List<City> result { get; set; }
}
So it uses the List result to store data. This works fine when I get a JSON array back, it stores them all easily. However if I just query for 1 city, I get an exception about it needing an array. Here is the code for my call:
async private Task<City.CityResponse> GetCityInformation(string url)
{
var client = new HttpClient();
var response = await client.GetAsync(new Uri(url));
string result = await response.Content.ReadAsStringAsync();
var cityRoot = JsonConvert.DeserializeObject<City.CityResponse>(result);
return cityRoot;
}
Is it possible for me to store 1 city in the list too? Or do I need to make a seperate cities class or how do I go about this? Thanks
Upvotes: 0
Views: 4145
Reputation: 71
Here's a small solution based on Jim's answer.
class CityResponse
{
public string status { get; set; }
public object result
{
get { return null; }
set
{
cities = new List<City>();
if (value.GetType() == typeof(JArray))
{
cities = ((JArray)value).ToObject<List<City>>();
foreach(var city in cities) city.ParentResponse = this; // Edit
return;
}
if (value.GetType() != typeof(JObject))
return;
cities.Add(((JObject)value).ToObject<City>());
foreach(var city in cities) city.ParentResponse = this; // Edit
}
}
public string message { get; set; }
public List<City> cities { get; internal set; }
}
Hope it helps!
PS: I don't know if the system that provides the JSON data is created by you, but having a member with an inconsistent type is bad design.
-- Edit --
In reply to a comment on this answer, asking on how to access the CityResponse from a City object, here's how I would do it:
I would add a new property to the City class, which would be meant for holding the parent CityResponse
public class City
{
public string id { get; set; }
...
public CityResponse ParentResponse { get; set;}
}
And then perform some minor changes to the setter, as seen in the original portion of the answer above.
Upvotes: 1
Reputation: 3036
instead of:
public class CityResponse
{
public string status { get; set; }
public string message { get; set; }
public List<City> result { get; set; }
}
try:
public class CityResponse
{
public string status { get; set; }
public string message { get; set; }
public string result {
get{ return null; }
set{
// if 1st character is "[" then it's an array of City, otherwise a City object
//depending on the above parse this string (which is like "{prop1: qqq, prop2: www}"
// or like "[{prop1: qqq, prop2: www}, {prop1: eee, prop2: eee}]")
// by the existing serializer or other one
// into City or array of cities
// if City, then convert in to array of cities
// and save result into realResult
}
}
public List<City> realResult { get; set; }
Upvotes: 1