【问题标题】:Hot to create DTO object to parse the multi-layer nested Json data热创建DTO对象解析多层嵌套Json数据
【发布时间】:2021-10-05 20:15:11
【问题描述】:

我正在使用 API,其中响应由多层嵌套 JSON 表示。

{
    "name": "Example",
    "settings": {
        "exampleOne": "value",
        "exampleTwo": 100,
        "exampleThree": {
            "subexampleOne": "value",
            "subexampleTwo": "value"
        },
        "arrayProperty": [
            {"subexampleOne": "value"},
            {"subexampleTwo": "value"}
        ]
    }
}

Settings 支持简单属性(数字、字符串等)、具有内部属性或属性数组的复杂类型。我无法预测 JSON 会有多少级别。

如何为此类 JSON 建模正确的 DTO?我应该只使用字符串、JObject 还是完全不同的方法?

【问题讨论】:

  • 以上所有。如果不知道实际内容可能是什么,我们就无法猜测。也许您可以创建一个自引用类型,也许不能。也许您只需要为其中一个属性这样做,也许不需要。大多数 JSON 文档都是嵌套的。都是字典和数组。 现实的例子会更有用
  • A JObject 匹配 any 对象,因此在最坏的情况下,您可以将整个文档解析为单个 JObject 并逐个检查其元素。或者使用 JsonDocument 来处理对象和数组。如果文档模式完全是任意的,您可能没有其他选择。不过这种情况很少见。
  • @PanagiotisKanavos ,JSON 代表设备配置。一般来说,文档说设置是动态的,结构取决于设备。我可以预测的唯一一件事是设置节点是必需的。但究竟会在设置中放置什么 - 我不知道。
  • 如果您不知道会发生什么,您将如何阅读?无论如何,如果内容是完全动态的,您应该使用 JObject。文档更有可能在顶层具有一些固定部分以及动态设置。您可以使用具有固定设置属性的 DTO 和用于动态部分的 dynamicJObjectJArray。如果唯一固定的部分是namesettings,那可能不值得。
  • @PanagiotisKanavos,你当然是对的 - 在设置下我有一些固定属性,如名称、设备 ID 等。我在这里展示了从我的角度来看有问题的部分 - 动态设置。跨度>

标签: c# asp.net-core json.net


【解决方案1】:

由于 json 是动态的,我建议使用 JobjectJToken 来解析 JSON 并根据 JTokenType 做出决定

var jsonString = File.ReadAllText("json1.json");
var jObj = JObject.Parse(jsonString);
foreach (var x in jObj)
{
    string name = x.Key;
    JToken value = x.Value;
    if (name == "settings")
    {
        foreach (var y in (JObject)x.Value)
        {
            string name1 = y.Key;
            JToken value1 = y.Value;
            switch (value1.Type)
            {
                case JTokenType.String:
                    Console.WriteLine($"it is string {value1}");
                    break;
                case JTokenType.Integer:
                    Console.WriteLine($"it is number {value1}");
                    break;
                case JTokenType.Array:
                    Console.WriteLine($"it is array {value1}");
                    break;
                case JTokenType.Object:
                    Console.WriteLine($"it is object {value1}");
                    break;
                default:
                    Console.WriteLine($"type not defined {value1}");
                    break;
            }
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-03
    • 1970-01-01
    • 1970-01-01
    • 2015-04-23
    • 1970-01-01
    相关资源
    最近更新 更多