0

I've tried various solutions from Google but to no avail.

I retrieve the JSON object from the API. When I try to deserialize this into my class object, it does not work (and I get 'Null object reference' in my code on the proceeding lines):

using (WebClient client = new WebClient())
{
    string json = client.DownloadString(url);
    JavaScriptSerializer serializer = new JavaScriptSerializer();
    WeatherInfo weatherinfo = serializer.Deserialize<WeatherInfo>(json);

    lblCity_Country.Text = weatherinfo.city.name + "," + weatherinfo.city.country;
    lblDescription.Text = weatherinfo.list[0].weather[0].description;

    lblTempMin.Text = string.Format("{0}.c", Math.Round(weatherinfo.list[0].temp.min, 1));
    lblTempMax.Text = string.Format("{0}.c", Math.Round(weatherinfo.list[0].temp.max, 1));

    lblHumidity.Text = weatherinfo.list[0].humidity.ToString();
    tblWeather.Visible = true;
}

The weatherinfo object remains null after deserializing the json object.

The associated classes:

public class WeatherInfo
{
    public City city { get; set; }
    public List<List> list { get; set; }
}

public class City
{
    public string name { get; set; }
    public string country { get; set; }
}

JSON:

{
    "coord": {
        "lon": -0.13,
        "lat": 51.51
    },
    "weather": [{
        "id‌​": 501,
        "main": "Ra‌​in",
        "description"‌​: "moderate rain",
        "icon": "10d"
    }],
    "base": "stations",
    "main": {
        "‌​temp": 14.54,
        "press‌​ure": 1015,
        "humidit‌​y": 87,
        "temp_min": ‌​13,
        "temp_max": 16
    },
    ‌​"visibility": 10000‌​,
    "wind": {
        "speed"‌​: 2.6,
        "deg": 340
    },
    "‌​clouds": {
        "all": 92‌​
    },
    "dt": 1502279400,
    ‌​"sys": {
        "type": 1,
        ‌​"id": 5091,
        "messag‌​e": 0.0123,
        "country‌​": "GB",
        "sunrise‌​": 1502253448,
        "sunse‌​t": 1502307198
    },
    "id‌​": 2643743,
    "name": ‌​"London",
    "cod": 2‌​00
}

What am I doing wrong?

Massimiliano Kraus
  • 3,638
  • 5
  • 27
  • 47
Metzer
  • 211
  • 1
  • 6
  • 20
  • 1
    what does json variable contains? – Hameed Syed Aug 09 '17 at 10:37
  • Can you add a sample of the json that you are receiving? – Popa Andrei Aug 09 '17 at 11:31
  • I don't know what you are trying to do with `WeatherInfo.list` but I doubt a List of List is really what you want. – Crowcoder Aug 09 '17 at 12:07
  • Json contains : "{\"coord\":{\"lon\":-0.13,\"lat\":51.51},\"weather\":[{\"id\":501,\"main\":\"Rain\",\"description\":\"moderate rain\",\"icon\":\"10d\"}],\"base\":\"stations\",\"main\":{\"temp\":14.54,\"pressure\":1015,\"humidity\":87,\"temp_min\":13,\"temp_max\":16},\"visibility\":10000,\"wind\":{\"speed\":2.6,\"deg\":340},\"clouds\":{\"all\":92},\"dt\":1502279400,\"sys\":{\"type\":1,\"id\":5091,\"message\":0.0123,\"country\":\"GB\",\"sunrise\":1502253448,\"sunset\":1502307198},\"id\":2643743,\"name\":\"London\",\"cod\":200}" I guess these back slashes are causing issues? – Metzer Aug 09 '17 at 12:13
  • The list of list was so that I can eventually pass multiple cities, to get the weather – Metzer Aug 09 '17 at 12:14
  • That json has no `city` nor `list` property. Deserialization requires the ability to find matching nodes by name and type. – Crowcoder Aug 09 '17 at 12:17
  • But it has 'name' which I thought i was passing to 'weatherinfo.city.name' I'm pretty new to using serializes/deserializers so apologies for my lack of understanding! – Metzer Aug 09 '17 at 12:46

2 Answers2

1

What am I doing wrong?

A lot, actually. Starting with: your WeatherInfo. It's all wrong - the JSON serializer needs an object that matches the JSON, or has attributes indicating why it doesn't match the JSON. Your object does neither.

In order to work it, we need the objects to match up, the following POCO's should work:

public class WeatherInfo
{
    public Coordinate coord { get; set; }
    public Weather[] weather { get; set; }
    public string base { get; set; }
    public MainInfo main { get; set; }
    public float visibility { get; set; }
    public WindInfo wind { get; set; }
    public CloudInfo clouds { get; set; }
    public long dt { get; set; }
    public SysInfo sys { get; set; }
    public int id { get; set; }
    public string name { get; set; }
    public int cod { get; set; }
}
public class SysInfo
{
    public int type { get; set; }
    public int id { get; set; }
    public float message { get; set; }
    public string country { get; set; }
    public long sunrise { get; set; }
    public long sunset { get; set; }
}
public class CloudInfo
{
    public float all { get; set; }
}
public class WindInfo
{
    public float speed { get; set; }
    public float deg { get; set; }
}
public class MainInfo
{
    public float temp { get; set; }
    public float pressure { get; set; }
    public float humidity { get; set; }
    public float temp_min { get; set; }
    public float temp_max { get; set; }
}
public class Weather
{
    public int id { get; set; }
    public string main { get; set; }
    public string description { get; set; }
    public string icon { get; set; }
}
public struct Coordinate
{
    public float lat { get; set; }
    public float lon { get; set; }
}

Once you've done that, it should be trivial to navigate the information to collect what you want. You should also consider looking up what attributes your serializer may use so that you can name these properties in accordance with .NET naming conventions, and use the attribute to specify what JSON name they have. The JSON.NET and JavaScriptSerializer items both support various attribute types to do this, if you're using a home-brew serializer you may or may not have one, but it looks like you're using the built-in JavaScriptSerializer, so I recommend you look up the attributes it uses and update these models in your work accordingly.

Der Kommissar
  • 5,848
  • 1
  • 29
  • 43
  • do we have to match up every item from the json object into our class members? Im only interested in 1 or 2 items such as temperature and name of city, thus my classes only had those 2 members – Metzer Aug 09 '17 at 13:02
  • @Metzer No, omitting them entirely would be fine. The serializer just won't look for those properties. – Der Kommissar Aug 09 '17 at 13:03
0

Your code seems correct, you need to check your JSON object. This another post on stack overflow should be useful for you.

tech-y
  • 1,829
  • 2
  • 16
  • 26