0

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




                }
            }
        }
0

2 Answers 2

1

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();
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

This does not work. I receive the following error: Cannot deserialize the current json object because(e.g.{"name":"value"}) into type because the type requires a json array (e.g.[1,2,3]) to deserialize correctly.
Works for me, the error you have mentioned is because the json is an array, you need to deserialise it to an array object
1

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

6 Comments

This does not work. I receive the following error: Cannot deserialize the current json object because(e.g.{"name":"value"}) into type because the type requires a json array (e.g.[1,2,3]) to deserialize correctly.
Are you using same url that you mentioned in your question? Because I used same url and you see the output screenshot above.
I'd just copy my above code and see its working. See and copy my working code from here => rextester.com/CXC11207
In above link working code you see the 10 cities wheather details in output window.
@CodingWoman, What about this..is this solved your problem, let me know?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.