AimalKhan AimalKhan - 6 months ago 21
JSON Question

Trouble parsing forecast.io weather data with Json.Net

I am relatively new to JSON and using an API

forecast.io
. It returns the JSON below, which I need to parse.

"daily":{
"summary":"Drizzle on Monday and Tuesday, with temperatures bottoming out at 91°F on Monday.","icon":"rain",
"data":[{
"time":1463770800,"summary":"Clear throughout the day.","icon":"clearday","sunriseTime":1463788956,"sunsetTime":1463839653,"moonPhase":0.48,"precipIntensity":0,"precipIntensityMax":0,"precipProbability":0,"temperatureMin":63.06,"temperatureMinTime":1463785200,"temperatureMax":95.23,"temperatureMaxTime":1463824800,"apparentTemperatureMin":63.06,"apparentTemperatureMinTime":1463785200,"apparentTemperatureMax":90.3,"apparentTemperatureMaxTime":1463824800,"dewPoint":37.34,"humidity":0.25,"windSpeed":3.44,"windBearing":22,"cloudCover":0,"pressure":1002.14,"ozone":283.7}


I extracted the "daily" portion successfully, but I could not get the "data" inside the "daily". I need to have the details, i.e. summary, time, icon, etc. I'd really appreciate some help.

Here is my C# code:

var test = new System.Net.WebClient().DownloadString("https://api.forecast.io/forecast/f2857958690caafc67d0dfba402c1f57/" + Latitude + "," + Longitude);

var json = JObject.Parse(test);
var daily = json.ToObject<DailyWeatherDTO>();

public class DailyWeatherDTO
{
public DailyWeatherData daily { get; set; }
}

public class DailyWeatherData
{
public daily data { get; set; }
}

public class daily
{
public string time { get; set; }
public String summary { get; set; }
public String icon { get; set; }
public String precipIntensity { get; set; }
public String precipProbability { get; set; }
public string sunriseTime { get; set; }
public string sunsetTime { get; set; }
public string moonPhase { get; set; }
public string precipIntensityMax { get; set; }
public string temperatureMin { get; set; }
public string temperatureMinTime { get; set; }
public string temperatureMax { get; set; }
public string temperatureMaxTime { get; set; }
public string apparentTemperatureMin { get; set; }
public string apparentTemperatureMinTime { get; set; }
public string apparentTemperatureMax { get; set; }
public string apparentTemperatureMaxTime { get; set; }
public string dewPoint { get; set; }
public string humidity { get; set; }
public string windSpeed { get; set; }
public string windBearing { get; set; }
public string cloudCover { get; set; }
public string pressure { get; set; }
public string ozone { get; set; }
}

Answer

First of all, the JSON you posted is not valid as shown. Specifically, you are missing a closing square bracket and curly brace at the end; plus, the whole thing needs to be enclosed in another pair of curly braces to be valid. Here is the corrected version, reformatted for readability:

{
  "daily": {
    "summary": "Drizzle on Monday and Tuesday, with temperatures bottoming out at 91°F on Monday.",
    "icon": "rain",
    "data": [
      {
        "time": 1463770800,
        "summary": "Clear throughout the day.",
        "icon": "clearday",
        "sunriseTime": 1463788956,
        "sunsetTime": 1463839653,
        "moonPhase": 0.48,
        "precipIntensity": 0,
        "precipIntensityMax": 0,
        "precipProbability": 0,
        "temperatureMin": 63.06,
        "temperatureMinTime": 1463785200,
        "temperatureMax": 95.23,
        "temperatureMaxTime": 1463824800,
        "apparentTemperatureMin": 63.06,
        "apparentTemperatureMinTime": 1463785200,
        "apparentTemperatureMax": 90.3,
        "apparentTemperatureMaxTime": 1463824800,
        "dewPoint": 37.34,
        "humidity": 0.25,
        "windSpeed": 3.44,
        "windBearing": 22,
        "cloudCover": 0,
        "pressure": 1002.14,
        "ozone": 283.7
      }
    ]
  }
}

To be able to get all the data, your class structure needs to match the structure of the JSON. Assuming the above represents the complete JSON, here is what your classes should look like. In particular, notice the data property of the DailyWeatherData class is defined as a list of items (not a single object), which corresponds to the square brackets for the data property in the JSON.

public class DailyWeatherDTO  // root-level container object
{
    public DailyWeatherData daily { get; set; }
}

public class DailyWeatherData
{
    public string summary { get; set; }
    public string icon { get; set; }
    public List<WeatherItem> data { get; set; }
}

public class WeatherItem
{
    public int time { get; set; }
    public string summary { get; set; }
    public string icon { get; set; }
    public int sunriseTime { get; set; }
    public int sunsetTime { get; set; }
    public double moonPhase { get; set; }
    public int precipIntensity { get; set; }
    public int precipIntensityMax { get; set; }
    public int precipProbability { get; set; }
    public double temperatureMin { get; set; }
    public int temperatureMinTime { get; set; }
    public double temperatureMax { get; set; }
    public int temperatureMaxTime { get; set; }
    public double apparentTemperatureMin { get; set; }
    public int apparentTemperatureMinTime { get; set; }
    public double apparentTemperatureMax { get; set; }
    public int apparentTemperatureMaxTime { get; set; }
    public double dewPoint { get; set; }
    public double humidity { get; set; }
    public double windSpeed { get; set; }
    public int windBearing { get; set; }
    public int cloudCover { get; set; }
    public double pressure { get; set; }
    public double ozone { get; set; }
}

With this class structure, you can deserialize the JSON like this:

DailyWeatherDTO dto = JsonConvert.DeserializeObject<DailyWeatherDTO>(json);

Here is a demo: https://dotnetfiddle.net/YTBrac

Comments