Ayohaych
Ayohaych

Reputation: 5189

C# adding JSON string to a List

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

Answers (2)

OrfeasZ
OrfeasZ

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

LINQ2Vodka
LINQ2Vodka

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

Related Questions