1

This is the Json I am trying to parse/deserialize

{
    "transactionId": "c34625a5-0590-48aa-8d1a-978df9aa9010",
    "dal": {
        "HourlyForecast": {
            "geocode:40.77,-73.96:language:en-US:units:e": {
                "data": {
                    "id": "40.77,-73.96",
                    "vt1hourlyForecast": [{
                        "processTime": "2017-07-12T12:00:00-0400",
                        "temperature": 85,
                        "precipPct": 15,
                        "precipType": "rain",
                        "uvIndex": 8,
                        "icon": 30,
                        "iconExtended": 3000,
                        "windDirCompass": "WSW",
                        "windDirDegrees": 253,
                        "windSpeed": 6,
                        "phrase": "Partly Cloudy",
                        "dayInd": "D",
                        "severity": 1,
                        "rh": 62,
                        "feelsLike": 92
                    }
                    //rest of json

I need to access vt1hourlyForecast[] I've tried the dynamic JObject approach here

dynamic hourlydata = JObject.Parse(jsonData);
string hourlyForecast = hourlydata["Vt1hourlyForecast"].ToString();
Console.WriteLine(hourlydata);

But I get the error "Cannot perform runtime binding on a null reference" I am really stuck on how to properly parse this. I have read a lot of similar questions but the nested Json is really confusing me any help will be greatly appreciated.

maccettura
  • 10,514
  • 3
  • 28
  • 35
T.W.
  • 19
  • 1
  • 6

2 Answers2

0

You need to navigate to the list property vt1hourlyForecast, since it's not a property of the outer object, but of a nested property e.g.

JObject jObject = JObject.Parse(json);

var dal = jObject["dal"];
var hourlyForecast = dal["HourlyForecast"];
var geocode = hourlyForecast["geocode:40.77,-73.96:language:en-US:units:e"];
var data = geocode["data"];
JArray forecast=  (JArray)data["vt1hourlyForecast"];

foreach (JProperty forecastProperty in forecast)
{
     Console.WriteLine(forecastProperty.Value);
}

In the example code I'm just casting the property to a JArray to show that that's possible, and it's enumerable.

kkirk
  • 352
  • 1
  • 7
  • I used IList vtls = forecasts.ToList(); foreach(JToken tok in vtls) { Console.WriteLine($"Process Time: {(string)tok.SelectToken("processTime")}"); } which worked instead – T.W. Jul 12 '17 at 19:18
0

Look at this answer:

You can do the following:

dynamic myNewObject = JsonConvert.DeserializeObject(json); which will return a dynamic object which you can work with.

Console.WriteLine(myNewObject.data[0].description); Obviously, it will fail if your JSON doesn't contain data array having objects with description property.

The whole question/answer: https://stackoverflow.com/a/34284972/5056173

Based on this, you can use NewtonSoft Json to get the properties.


Another way is to filter it by yourself:

        var startIndex = json.IndexOf("vt1hourlyForecast")-1;
        var filteredJson1 = json.Substring(startIndex, json.Length - startIndex);
        var endIndex = filteredJson1.IndexOf("}]")+2;
        var filteredJson2 = filteredJson1.Substring(0, endIndex);
        var jsonValidFilteredJson = "{"+filteredJson2+"}";

        var yourObject = JsonConvert.DeserializeObject<Vt1hourlyForecast>(jsonValidFilteredJson);

You can use this class:

public class Vt1hourlyForecast
{
    public string processTime { get; set; }
    public int temperature { get; set; }
    public int precipPct { get; set; }
    public string precipType { get; set; }
    public int uvIndex { get; set; }
    public int icon { get; set; }
    public int iconExtended { get; set; }
    public string windDirCompass { get; set; }
    public int windDirDegrees { get; set; }
    public int windSpeed { get; set; }
    public string phrase { get; set; }
    public string dayInd { get; set; }
    public int severity { get; set; }
    public int rh { get; set; }
    public int feelsLike { get; set; }
}
Sean Stayns
  • 4,082
  • 5
  • 25
  • 35