Andrei Cucuruzac
Andrei Cucuruzac

Reputation: 9

Cannot deserialize the current JSON.Net array C#

I'm pretty new to programming , I still have a lot to learn and I would need a little help please :) !

I saw in other posts the same error but I could not solve anything even with those explanations

The error i get

Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'JSON_TEST2.Class1+weatherinfo' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly. To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array. Path 'weather', line 1, position 45.'

I have this class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;

namespace JSON_TEST2
{
    public class Class1
    {
        public class coord
        {
            public double lat { get; set; }
            public double lon { get; set; }
        }

        public class weatherinfo
        {
            public string[] weather { get; set; }
        }

        public class WeatherMain
        {
           public coord coord { get; set; }
           public weatherinfo weather { get; set; }

            public void display()
            {
                Console.WriteLine("lon: {0}", this.coord.lon);
                Console.WriteLine("lat: {0}", this.coord.lat);
                Console.WriteLine("id: {0}", this.weather.weather);
            }
        }     
    }
}

I deserialize with this

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.Net;

namespace JSON_TEST2
{
    class Program
    {
        static void Main()
        {
            WebClient wc = new WebClient();
            var json = wc.DownloadString(@"http://api.openweathermap.org/data/2.5/weather?q=Bucharest,ro&APPID=829b7bfc0558b9e501f43fc6087fca3a");
            Console.WriteLine(json);
            Class1.WeatherMain vreme = JsonConvert.DeserializeObject <Class1.WeatherMain>(json);
            vreme.display();
            Console.ReadLine();
        }
    }
}

This is the JSON I get from the server:

{
   "coord":{
      "lon":26.1,
      "lat":44.44
   },
   "weather":[
      {
         "id":804,
         "main":"Clouds",
         "description":"overcast clouds",
         "icon":"04n"
      }
   ],
   "base":"stations",
   "main":{
      "temp":287.64,
      "pressure":1012,
      "humidity":87,
      "temp_min":287.15,
      "temp_max":288.15
   },
   "visibility":8000,
   "wind":{
      "speed":2.6,
      "deg":50
   },
   "clouds":{
      "all":100
   },
   "dt":1573682313,
   "sys":{
      "type":1,
      "id":6911,
      "country":"RO",
      "sunrise":1573708189,
      "sunset":1573743018
   },
   "timezone":7200,
   "id":683506,
   "name":"Bucharest",
   "cod":200
}

Upvotes: 0

Views: 803

Answers (1)

Anu Viswan
Anu Viswan

Reputation: 18163

As described in comments, your classes doesn't match the Json.This is because the weather itself is an array, and not an object.

"weather":[
          {
             "id":804,
             "main":"Clouds",
             "description":"overcast clouds",
             "icon":"04n"
          }
       ]

You need to alter the weatherinfo and WeatherMain as following.

public class weatherinfo
{
    public int id { get; set; }
    public string main { get; set; }
    public string description { get; set; }
    public string icon { get; set; }
}

public class WeatherMain
{
   public coord coord { get; set; }
   public List<weatherinfo> weather { get; set; }

    public void display()
    {
        Console.WriteLine("lon: {0}", this.coord.lon);
        Console.WriteLine("lat: {0}", this.coord.lat);
        Console.WriteLine("id: {0}", string.Join(Environment.NewLine,this.weather.Select(c=>$"Weather:{c.main},Description:{c.description}")));
    }
} 

Demo Code

Upvotes: 1

Related Questions