简体   繁体   English

如何解析深度多层的JSON数据C#Json.Net

[英]How to parse JSON data that is multiple layers deep C# Json.Net

I am looking to read data from a WeatherAPI, http://www.aerisweather.com/support/docs/api/getting-started/responses/ 我正在寻找从WeatherAPI读取数据, http ://www.aerisweather.com/support/docs/api/getting-started/responses/

It has data that is several layers deep. 它具有几层深度的数据。 When using Json.Net. 使用Json.Net时。 I can parse the byte array that my WebClient.DownloadData method returns. 我可以解析WebClient.DownloadData方法返回的字节数组。 However, my results even after parsing this byte array are 3 key value pairs with the third key value pair being the results which consists of multiple key value pairs. 但是,即使在解析此字节数组之后,我的结果也是3个键值对,而第三个键值对是包含多个键值对的结果。

Any ideas on how to address this. 关于如何解决此问题的任何想法。

My code is below: 我的代码如下:

WebClient wc = new WebClient();

            var stream = wc.DownloadData("http://api.aerisapi.com/observations/milwaukee,wi?client_id=" + id +
                "&client_secret=" + secret + "");
            Dictionary<string, Object> jsonStr = parse(stream);
            Console.ReadLine();
        }
            public static Dictionary<String, Object> parse(byte[] stream)
        {
            string jsonStr = Encoding.UTF8.GetString(stream);
            return JsonConvert.DeserializeObject<Dictionary<String, Object>>(jsonStr);
        }

Here is the third value that the api call returns. 这是api调用返回的第三个值。

{[response, {
  "id": "KMKE",
  "loc": {
    "long": -87.9,
    "lat": 42.95
  },
  "place": {
    "name": "milwaukee",
    "state": "wi",
    "country": "us"
  },
  "profile": {
    "tz": "America/Chicago",
    "elevM": 206,
    "elevFT": 676
  },
  "obTimestamp": 1446677520,
  "obDateTime": "2015-11-04T16:52:00-06:00",
  "ob": {
    "timestamp": 1446677520,
    "dateTimeISO": "2015-11-04T16:52:00-06:00",
    "tempC": 19,
    "tempF": 66,
    "dewpointC": 14,
    "dewpointF": 57,
    "humidity": 73,
    "pressureMB": 1016,
    "pressureIN": 30,
    "spressureMB": 992,
    "spressureIN": 29.29,
    "altimeterMB": 1017,
    "altimeterIN": 30.03,
    "windKTS": 8,
    "windKPH": 15,
    "windMPH": 9,
    "windSpeedKTS": 8,
    "windSpeedKPH": 15,
    "windSpeedMPH": 9,
    "windDirDEG": 200,
    "windDir": "SSW",
    "windGustKTS": null,
    "windGustKPH": null,
    "windGustMPH": null,
    "flightRule": "LIFR",
    "visibilityKM": 16.09344,
    "visibilityMI": 10,
    "weather": "Clear",
    "weatherShort": "Clear",
    "weatherCoded": "::CL",
    "weatherPrimary": "Clear",
    "weatherPrimaryCoded": "::CL",
    "cloudsCoded": "CL",
    "icon": "clearn.png",
    "heatindexC": 19,
    "heatindexF": 66,
    "windchillC": 19,
    "windchillF": 66,
    "feelslikeC": 19,
    "feelslikeF": 66,
    "isDay": false,
    "sunrise": 1446640242,
    "sunriseISO": "2015-11-04T06:30:42-06:00",
    "sunset": 1446676779,
    "sunsetISO": "2015-11-04T16:39:39-06:00",
    "snowDepthCM": null,
    "snowDepthIN": null,
    "precipMM": 0,
    "precipIN": 0,
    "solradWM2": null,
    "light": 0,
    "sky": 0
  },
  "raw": "KMKE 042252Z 20008KT 10SM CLR 19/14 A3003 RMK AO2 SLP169 T01890139",
  "relativeTo": {
    "lat": 43.0389,
    "long": -87.90647,
    "bearing": 177,
    "bearingENG": "S",
    "distanceKM": 9.899,
    "distanceMI": 6.151
  }
}]}

If you do not want to re-create the object model, you can use dynamic JObject: 如果您不想重新创建对象模型,则可以使用动态JObject:

static void Main(string[] args)
{
    using (var wc = new WebClient())
    {
        var stream = wc.DownloadData("http://api.aerisapi.com/observations/milwaukee,wi?client_id=xxx&client_secret=xxx");
        dynamic jsonObject = Parse(stream);
        Console.WriteLine(jsonObject.success);
        Console.WriteLine(jsonObject.error);
        Console.WriteLine(jsonObject.response);
        Console.WriteLine(jsonObject.response.place.name);
    }
    Console.ReadLine();
}
public static JObject Parse(byte[] stream)
{
    var jsonStr = Encoding.UTF8.GetString(stream);
    return JObject.Parse(jsonStr);
}

You should create a corresponding class (and other classes for nested objects) and then create an instance of it and call 您应该创建一个对应的类(以及嵌套对象的其他类),然后创建它的一个实例并调用

JsonConvert.PopulateObject(jsonString, myObject);

The root object would look like 根对象看起来像

public class AerisWeatherResponse
{
    public bool success;
    public AerisWeatherError error; // a class with code and description fields
    public AerisWeatherResponseBody response;
}

And the AerisWeatherResponseBody class should look like: AerisWeatherResponseBody类应如下所示:

public class AerisWeatherResponseBody
{
    public string id;
    public AerisWeatherLocation; // a class with long and lat fields
    public AerisWeatherPlace; // a class with name, state and country fields
    .......
    .......
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM