C#:从JSON结构中提取/检索子节点

C#:从JSON结构中提取/检索子节点,c#,json,json.net,C#,Json,Json.net,如何从C#中的JSON结构中提取或检索子节点值 我的应用程序正在使用,我需要从城市检索名称,从列表检索临时以及从天气节点检索说明,我的JSON和类结构如下所示 { "cod": "200", "message": 0.0284, "city": { "id": 2643743, "name": "London", "coord": { "lon": -0.12574, "lat": 51.50853 }, "countr

如何从C#中的JSON结构中提取或检索子节点值

我的应用程序正在使用,我需要从城市检索名称,从列表检索临时以及从天气节点检索说明,我的JSON和类结构如下所示

{
  "cod": "200",
  "message": 0.0284,
  "city": {
    "id": 2643743,
    "name": "London",
    "coord": {
      "lon": -0.12574,
      "lat": 51.50853
    },
    "country": "GB",
    "population": 0,
    "sys": {
      "population": 0
     }
  },
  "cnt": 1,
  "list": [
    {
      "dt": 1429268400,
      "temp": {
        "day": 12.21,
        "min": 4.86,
        "max": 13.18,
        "night": 4.86,
        "eve": 11.76,
        "morn": 12.21
      },
      "pressure": 1028.8,
      "humidity": 66,
      "weather": [
         {
           "id": 803,
           "main": "Clouds",
           "description": "broken clouds",
           "icon": "04d"
        }
      ],
      "speed": 5.9,
      "deg": 67,
      "clouds": 80
    }
  ]
}
C#Class

public class WeatherForeCast
{
    public string City { get; set; }
    public decimal Day { get; set; }
    public decimal Min { get; set; }
    public decimal Max { get; set; }
    public decimal Night { get; set; }
    public string Description { get; set; }
}

到目前为止,我还熟悉使用JSON.net将C#对象序列化和反序列化为结构完全相同的JSON。

使用json2csharp.com生成类

public class Coord
{
    public double lon { get; set; }
    public double lat { get; set; }
}

public class Sys
{
    public int population { get; set; }
}

public class City
{
    public int id { get; set; }
    public string name { get; set; }
    public Coord coord { get; set; }
    public string country { get; set; }
    public int population { get; set; }
    public Sys sys { get; set; }
}

public class Temp
{
    public double day { get; set; }
    public double min { get; set; }
    public double max { get; set; }
    public double night { get; set; }
    public double eve { get; set; }
    public double morn { 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 class List
{
    public int dt { get; set; }
    public Temp temp { get; set; }
    public double pressure { get; set; }
    public int humidity { get; set; }
    public List<Weather> weather { get; set; }
    public double speed { get; set; }
    public int deg { get; set; }
    public int clouds { get; set; }
}

public class RootObject
{
    public string cod { get; set; }
    public double message { get; set; }
    public City city { get; set; }
    public int cnt { get; set; }
    public List<List> list { get; set; }
}
公共类协作
{
公共双lon{get;set;}
公共双lat{get;set;}
}
公共类系统
{
公共整数填充{get;set;}
}
公营城市
{
公共int id{get;set;}
公共字符串名称{get;set;}
公共坐标{get;set;}
公共字符串国家{get;set;}
公共整数填充{get;set;}
公共系统系统{get;set;}
}
公共类临时工
{
公共双日{get;set;}
公共双最小值{get;set;}
公共双最大值{get;set;}
公共双人夜{get;set;}
公共双夏娃{get;set;}
公共双晨光{get;set;}
}
公共天气
{
公共int id{get;set;}
公共字符串main{get;set;}
公共字符串说明{get;set;}
公共字符串图标{get;set;}
}
公共班级名单
{
公共int dt{get;set;}
公共临时{get;set;}
公共双重压力{get;set;}
公共属性{get;set;}
公共天气列表{get;set;}
公共双速{get;set;}
公共整数{get;set;}
公共整数云{get;set;}
}
公共类根对象
{
公共字符串cod{get;set;}
公共双消息{get;set;}
公共城市城市{get;set;}
公共int cnt{get;set;}
公共列表{get;set;}
}
然后使用JSON.NET反序列化到类结构中,并提取所需的属性

var jsonObject = JsonConvert.DeserializeObject<RootObject>(jsonString);
var jsonObject=JsonConvert.DeserializeObject(jsonString);

您现在有了一个RootObject实例,可以根据需要遍历它以提取所需的特定值。

如果您只想填充
WeatherForecast
的实例,您可以在普通
JObject
上使用一些
SelectToken
调用:

var parsed = JObject.Parse(json);
var forecast = new WeatherForeCast();

forecast.City = parsed.SelectToken("city.name").Value<string>();
forecast.Day = parsed.SelectToken("list[0].temp.day").Value<decimal>();
forecast.Description = parsed.SelectToken("list[0].weather[0].description").Value<string>();
forecast.Min = parsed.SelectToken("list[0].temp.min").Value<decimal>();
forecast.Max = parsed.SelectToken("list[0].temp.max").Value<decimal>();
forecast.Night = parsed.SelectToken("list[0].temp.night").Value<decimal>();
var parsed=JObject.Parse(json);
var forecast=新天气预报();
forecast.City=parsed.SelectToken(“City.name”).Value();
forecast.Day=parsed.SelectToken(“列表[0].temp.Day”).Value();
forecast.Description=parsed.SelectToken(“列表[0].weather[0].Description”).Value();
forecast.Min=parsed.SelectToken(“列表[0].temp.Min”).Value();
forecast.Max=parsed.SelectToken(“列表[0].temp.Max”).Value();
forecast.Night=parsed.SelectToken(“列表[0].temp.Night”).Value();

请注意,这是非常脆弱的,它对JSON的内容进行了假设。如果JSON发生更改,则
SelectToken
中各种属性的路径将不正确,此代码将引发异常。

您需要创建一个与JSON对象具有相同结构的类。属性名称不必完全匹配(例如大写字母等)。您可以在每个属性上使用JsonProperty[]属性来设置名称。完成此操作后,可以使用JsonSerializer将JSON读入C#对象。如果你的应用程序中需要一个更简单的WeatherForecast对象,你可以将返回的JSON C#对象映射到你的WeatherForecast对象。你也可以不用类来实现这一点。例如:
DynamicJSONOBJ=JsonConvert.DeserializeObject(jsonStr);double msgDbl=(double)jsonObj.message
@Mangist我不想在我的项目中创建与JSON结构相同的所有类,我只想从JSON结构中获得一些属性值并填充WeatherForecast对象。@BeingDev您不需要WeatherForecast对象中的所有属性,但是你想从JSON对象中得到的类必须在相同的路径/结构中,以便序列化程序可以解析它们。谢谢Craig,但我只想在我的应用程序中维护WeatherForecast类,我不想创建你列出的所有类。然后你需要使用
JObject.parse
反序列化为动态,然后使用“魔弦“以访问所需的属性。然而,在我看来,这将比简单地将生成的类复制粘贴到应用程序中,然后使用强类型属性要复杂得多。我认为你做出了错误的选择,但这是你的应用程序。谢谢Craig,直到现在我还不知道如何使用
JObject.Parse
,我得到了解决方案。