user10762490
user10762490

Reputation:

Parsing JSON using httpClient.SendAsync(request) via a foreach loop

I am using NewtonSoft to parse a JSON Api call.

The code must remain in the same format it is in.

My only problem is that I cannot iterate through the values of the JSON in a foreach loop.

How can I solve this problem?

My Working Code

public async Task callWebApi()
    {
        using (var httpClient = new HttpClient())
        {
            using (var request = new HttpRequestMessage(new HttpMethod("GET"), "https://www.metaweather.com/api/location/search/?lattlong=50.068,-5.316"))
            {
                var response = await httpClient.SendAsync(request);

                using (HttpContent content = response.Content)
                {


                    var jsonString = await response.Content.ReadAsStringAsync();
                    var data = JsonConvert.DeserializeObject<Object>(jsonString);
                Console.WriteLine("I need to parse distance, title, location_type, woeid,latt_long so that I can iterate through it using a foreach loop");
                Console.WriteLine(data);
                Console.Read();
                    // I don't know how to get the values of the json




                }
            }
        }

Upvotes: 0

Views: 2657

Answers (2)

er-sho
er-sho

Reputation: 9771

You just need only 2 line of code.

1) Parse your json to JToken.

2) Cast parsed JToken into array of JObject and from each JObject you can access each property by its key name.

...

using (HttpContent content = response.Content)
{
    var jsonString = await response.Content.ReadAsStringAsync();

    //1
    JToken jToken = JToken.Parse(jsonString);

    //2
    JObject[] items = jToken.ToObject<JObject[]>();

    foreach (var item in items)
    {
        Console.WriteLine(item["distance"]);
        Console.WriteLine(item["latt_long"]);
        Console.WriteLine(item["location_type"]);
        Console.WriteLine(item["title"]);
        Console.WriteLine(item["woeid"]);
        Console.WriteLine();
    }

    Console.Read();
}

Output:

enter image description here

Upvotes: 1

traveler3468
traveler3468

Reputation: 1656

First of all, I dont think its a great idea to have external links to other sites with the code you're working with.

With that being said, you need to know what the json is first and then create an appropriate class for it, in your case the json looks like this

[{"distance":16744,"title":"Penzance","location_type":"City","woeid":31889,"latt_long":"50.11861,-5.53723"},{"distance":19287,"title":"Falmouth","location_type":"City","woeid":19894,"latt_long":"50.151001,-5.07832"},{"distance":19904,"title":"St Ives","location_type":"City","woeid":35662,"latt_long":"50.21032,-5.48569"},{"distance":28619,"title":"Truro","location_type":"City","woeid":38283,"latt_long":"50.263691,-5.054610"},{"distance":90542,"title":"Plymouth","location_type":"City","woeid":32185,"latt_long":"50.375801,-4.136890"},{"distance":146738,"title":"Exeter","location_type":"City","woeid":19792,"latt_long":"50.720760,-3.515340"},{"distance":162575,"title":"Sidmouth","location_type":"City","woeid":34811,"latt_long":"50.687439,-3.23757"},{"distance":197916,"title":"Swansea","location_type":"City","woeid":36758,"latt_long":"51.623150,-3.940930"},{"distance":217189,"title":"Cardiff","location_type":"City","woeid":15127,"latt_long":"51.481251,-3.180730"},{"distance":245712,"title":"Bristol","location_type":"City","woeid":13963,"latt_long":"51.453732,-2.591560"}]

And the class would look something like this.

public class WeatherClass
{
    public int distance { get; set; }
    public string title { get; set; }
    public string location_type { get; set; }
    public int woeid { get; set; }
    public string latt_long { get; set; }
}

Once you have that, because your response is an array object, when we deserialize the json, we need to tell it that it's an array so it knows it can expect more than one object item at a time.

So something like this would be needed to deserialize the response content data.

List<WeatherClass> data = Newtonsoft.Json.JsonConvert.DeserializeObject<List<WeatherClass>>(jsonString);

Once you have your data that contains the deserialized json and has it in an array, You are free to do with it what you want.

In my case, here is what a loop would look like.

foreach (var weatherItem in data)
{
      Console.WriteLine(weatherItem.distance);
      Console.WriteLine(weatherItem.latt_long);
      Console.WriteLine(weatherItem.location_type);
      Console.WriteLine(weatherItem.title);
      Console.WriteLine(weatherItem.woeid);
}

Here is your code with my changes.

public class WeatherClass
{
    public int distance { get; set; }
    public string title { get; set; }
    public string location_type { get; set; }
    public int woeid { get; set; }
    public string latt_long { get; set; }
}

public async Task callWebApi()
{
    using (var httpClient = new HttpClient())
    {
        using (var request = new HttpRequestMessage(new HttpMethod("GET"), "https://www.metaweather.com/api/location/search/?lattlong=50.068,-5.316"))
        {
            var response = await httpClient.SendAsync(request);
            using (HttpContent content = response.Content)
            {
                var jsonString = await response.Content.ReadAsStringAsync();
                List<WeatherClass> data = Newtonsoft.Json.JsonConvert.DeserializeObject<List<WeatherClass>>(jsonString);

                foreach (var weatherItem in data)
                {
                    Console.WriteLine(weatherItem.distance);
                    Console.WriteLine(weatherItem.latt_long);
                    Console.WriteLine(weatherItem.location_type);
                    Console.WriteLine(weatherItem.title);
                    Console.WriteLine(weatherItem.woeid);
                }
            }
        }
    }
}

static void Main()
{
    Program P1 = new Program();

    try
    {
        P1.callWebApi().Wait();

    }
    catch (Exception ex)
    {
        Console.WriteLine("There was an exception, {0}", ex.ToString());
        Console.Read();
    }
}

Upvotes: 1

Related Questions