阅读卡住 JSON 儿童使用 Newtonsoft.json

Getting stuck reading JSON Children using Newtonsoft.json

我在读取根元素的子元素和理解我在下面的 JSON 中出错的地方时遇到问题:

{
  "001": {
    "peers": [
      {
        "id": 0,
        "server": "1.1.1.1:80",
        "name": "1.1.1.1:80",
        "backup": false,
        "weight": 1,
        "state": "up",
        "active": 0,
        "requests": 0,
        "responses": {
          "1xx": 0,
          "2xx": 0,
          "3xx": 0,
          "4xx": 0,
          "5xx": 0,
          "total": 0
        },
        "sent": 0,
        "received": 0,
        "fails": 0,
        "unavail": 0,
        "health_checks": {
          "checks": 0,
          "fails": 0,
          "unhealthy": 0
        },
        "downtime": 0
      },
      {
        "id": 1,
        "server": "127.0.0.1:8888",
        "name": "127.0.0.1:8888",
        "backup": false,
        "weight": 1,
        "state": "down",
        "active": 0,
        "requests": 0,
        "responses": {
          "1xx": 0,
          "2xx": 0,
          "3xx": 0,
          "4xx": 0,
          "5xx": 0,
          "total": 0
        },
        "sent": 0,
        "received": 0,
        "fails": 0,
        "unavail": 0,
        "health_checks": {
          "checks": 0,
          "fails": 0,
          "unhealthy": 0
        },
        "downtime": 0
      }
    ],
    "keepalive": 0,
    "zombies": 0,
    "zone": "001"
  },
  "002": {
    "peers": [
      {
        "id": 0,
        "server": "1.1.1.2:80",
        "name": "1.1.1.2:80",
        "backup": false,
        "weight": 1,
        "state": "up",
        "active": 0,
        "requests": 0,
        "responses": {
          "1xx": 0,
          "2xx": 0,
          "3xx": 0,
          "4xx": 0,
          "5xx": 0,
          "total": 0
        },
        "sent": 0,
        "received": 0,
        "fails": 0,
        "unavail": 0,
        "health_checks": {
          "checks": 0,
          "fails": 0,
          "unhealthy": 0
        },
        "downtime": 0
      },
      {
        "id": 1,
        "server": "127.0.0.1:8888",
        "name": "127.0.0.1:8888",
        "backup": false,
        "weight": 1,
        "state": "down",
        "active": 0,
        "requests": 0,
        "responses": {
          "1xx": 0,
          "2xx": 0,
          "3xx": 0,
          "4xx": 0,
          "5xx": 0,
          "total": 0
        },
        "sent": 0,
        "received": 0,
        "fails": 0,
        "unavail": 0,
        "health_checks": {
          "checks": 0,
          "fails": 0,
          "unhealthy": 0
        },
        "downtime": 0
      }
    ],
    "keepalive": 0,
    "zombies": 0,
    "zone": "002"
  }
}

我知道我可以将 JSON 传递到 JObject 并通过命名 001 JSON 对象找到下面的服务器值:

JObject obj = JObject.Parse(jsonResponse);

var h = obj.Value<JObject>("001").Value<JArray>("peers")[0].SelectToken("server").ToString();

但是我想读取根元素的子元素(我认为是对象 001002),不管它们的名称如何,通过它们查找键的值“区域”和“保持活动”。我以为我可以做到这一点:

List<JToken> toks = obj.Root.Children().ToList<JToken>();

string output = "";
foreach (JToken token in toks)
{
    JProperty prop = (JProperty)token;
    output += prop.Value<string>("zone");  // returns nothing
    string bla = token.ToString();  //returns 001 and all it's child objects
}

但输出字符串为空。我可以看到,如果我尝试 token.ToString()JToken 对象中有内容,但我似乎无法读取它。

如果我使用 Visual studio 创建一个反序列化对象,我会得到这个根对象,这让我更加困惑:

public class Rootobject
{
    public 001 001 { get; set; }
    public 002 002 { get; set; }
}

我做错了什么?任何帮助将不胜感激。

乔恩

如果您尝试使用 JTokens 解析此 JSON,您需要了解不同种类的可能标记以及它们之间的关系。您可能会从阅读 .

中受益

在根目录你有一个对象;这个对象有两个属性,叫做“001”和“002”。这些属性各自的值又是对象,包含它们自己的属性(“peers”、“keepalive”、“zombies”和“zone”)。等等。

如果您最终想在不知道其名称的情况下遍历根属性,然后转储子对象的“zone”和“keepalive”属性的值,您可以这样做:

var obj = JObject.Parse(json);
foreach (JProperty prop in obj.Properties())
{
    var item = (JObject)prop.Value;
    var zone = (string)item["zone"];
    var keepalive = (int)item["keepalive"];
    Console.WriteLine($"Zone: {zone} keepalive: {keepalive}");
}

Fiddle: https://dotnetfiddle.net/tNut9v

如果 JTokens 让您头晕目眩,那么您最好为 JSON 声明 classes。唯一的问题是根中的动态 属性 名称(“001”、“002”)。但是您可以通过反序列化为 Dictionary<string, T> 来处理该问题,其中 TItem class,如下所示。像这样定义 classes:

public class Item
{
    public List<Peer> peers { get; set; }
    public int keepalive { get; set; }
    public int zombies { get; set; }
    public string zone { get; set; }
}

public class Peer
{
    public int id { get; set; }
    public string server { get; set; }
    public string name { get; set; }
    public bool backup { get; set; }
    public int weight { get; set; }
    public string state { get; set; }
    public int active { get; set; }
    public int requests { get; set; }
    public Responses responses { get; set; }
    public int sent { get; set; }
    public int received { get; set; }
    public int fails { get; set; }
    public int unavail { get; set; }
    public HealthChecks health_checks { get; set; }
    public int downtime { get; set; }
}

public class Responses
{
    [JsonProperty("1xx")]
    public int code_1xx { get; set; }
    [JsonProperty("2xx")]
    public int code_2xx { get; set; }
    [JsonProperty("3xx")]
    public int code_3xx { get; set; }
    [JsonProperty("4xx")]
    public int code_4xx { get; set; }
    [JsonProperty("5xx")]
    public int code_5xx { get; set; }
    public int total { get; set; }
}

public class HealthChecks
{
    public int checks { get; set; }
    public int fails { get; set; }
    public int unhealthy { get; set; }
}

然后你可以像这样反序列化并转储出你想要的数据:

var dict = JsonConvert.DeserializeObject<Dictionary<string, Item>>(json);
foreach (var kvp in dict)
{
    Item item = kvp.Value;
    Console.WriteLine($"Zone: {item.zone} keepalive: {item.keepalive}");
}

Fiddle: https://dotnetfiddle.net/3rRmxJ