一尘不染

如何从JSON字符串获取深度嵌套的属性?

json

如何使用JSON.NET从JSON中获取“ myThings”数组,如下所示?

范例1:

{
    "z": {
        "a": 1,
        "b": 2
    },
    "something": {
        "y": [1, 2],
        "somethingElse": {
            "1234": {
                "foo": "bar",
                "myThings": [{
                    "name": "bob",
                    "age": 3
                }, {
                    "name": "bob",
                    "age": 3
                }]
            }
        }
    }
}

范例2:

{
    "z": {
        "a": 1,
        "b": 2
    },
    "something": {
        "y": [1, 2],
        "somethingElse": {
            "7890": {
                "foo": "bar"
            }
        }
    }
}

我遇到的一些困难:

  • 属性名称之一是不可预测的数字(“ 1234”和“ 7890”)
  • 有时“ myThings”数组不存在-在这种情况下,我想要的是null或空数组/集合

可以帮助您的另一个考虑因素:我确实有一个静态类来表示myThings数组中的内容,所以我的理想返回值是 IEnumerable<MyThing>

我的第一个尝试是使用,JsonConvert.DeserializeObject<dynamic>(json)但是我不知道如何处理上面提到的问题。最后,我不需要整个JSON字符串的全部数据,只需要一个名为“
myThings”的数组即可。


阅读 305

收藏
2020-07-27

共1个答案

一尘不染

您可以JToken.SelectTokens()用于此目的。它允许使用通配符查询JSON和使用JSONPath语法进行递归搜索:

var root = JToken.Parse(json);
var myThings = root.SelectTokens("..myThings[*]").ToList();

".."递归下降 运算符,"myThings[*]"表示返回属性的所有数组项"myThings"

原型小提琴

如果的数组条目"myThings[*]"对应于某个POCO
MyThing,则可以JToken.ToObject<T>()在查询后使用反序列化它们:

    var myThings = root.SelectTokens("..myThings[*]").Select(t => t.ToObject<MyThing>()).ToList();
2020-07-27