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

时间:2016-03-31 04:58:00

标签: c# json json.net

如何使用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”的数组内部。

1 个答案:

答案 0 :(得分:4)

您可以使用JToken.SelectTokens()来实现此目的。它允许使用通配符和使用JSONPath syntax的递归搜索查询JSON:

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

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

原型fiddle

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

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