如何使用可变属性名反序列化 JSON

问题描述 投票:0回答:1

这是我反序列化过的最奇怪的 json。它在数组的每个项目中都有可变的属性名称:

{
    "id": 1000,
    "rows": [
        {
            "costPriceIncludingVat": 1000,
            "productInfo": {
                "depth": 600,
                "width": 2200,
                "parts": {
                    "876-08533": {
                        "depth": 0,
                        "width": 0,
                        "description": "Thing 3",
                        "properties": {
                            "measure": "0"
                        }
                    },
                    "cabinet-1": {
                        "depth": 600,
                        "width": 746,
                        "parts": {
                            "JW_876-76117_P": {
                                "depth": 0,
                                "width": 0,
                                "description": "Thing 1",
                                "properties": {
                                    "measure": "0"
                                }
                            }
                        },
                        "description": "Closet"
                    }
                },
                "description": "My description"
            }
        }
    ],
    "quotation": "ABCDEF"
}

我有“productInfo”节点作为这个 C# 类:

    public class ProductInfo
    {
        public int Depth;
        public int Width;
        public List<ProductInfo> Parts;
        public string Description;
        public Properties Properties;
    }

不要介意属性名称(大小写)的差异。

“parts”中的每个节点都是一个 ProductInfo,但节点的名称未命名为“productInfo”,因此反序列化器不知道如何将其反序列化。

我使用过 System.Text.Json 但它根本不反序列化。我刚刚获得根类的一个新实例。 Newtonsoft.Json 做得更好,但引发了一个异常:

无法反序列化当前 JSON 对象(例如 {"name":"value"}) 进入类型 'System.Collections.Generic.List`1[ConsoleTestApp.IvenzaTests.Models.ProductInfo]' 因为该类型需要 JSON 数组(例如 [1,2,3])来反序列化 正确。要修复此错误,请将 JSON 更改为 JSON 数组 (例如 [1,2,3])或更改反序列化类型,使其成为正常类型 .NET 类型(例如,不是像整数这样的原始类型,不是集合 类型(如数组或列表),可以从 JSON 反序列化 目的。也可以将 JsonObjectAttribute 添加到类型中以强制它 从 JSON 对象反序列化。

如何使解串器将部件数组中的每个项目识别为 ProductInfo? 最好使用 System.Text.Json。

c# json variables deserialization
1个回答
0
投票

根据你的json,你的ProductInfo是一个嵌套结构,所以你还应该暴露上面的一些级别

public class Root
{
    public int Id { get; set; }
    public List<Row> Rows { get; set; }
    public string Quotation { get; set; }
}

public class Row
{
    public decimal CostPriceIncludingVat { get; set; }
    public ProductInfo ProductInfo { get; set; }
}

在 ProductInfo 中,零件看起来必须是字典而不是列表,因为 json 中存在键值对

public class ProductInfo
{
    public int Depth { get; set; }
    public int Width { get; set; }
    public Dictionary<string, ProductInfo> Parts { get; set; } // Handle dictionary of parts
    public string Description { get; set; }
    public Properties Properties { get; set; }
}

如果重新排列数据结构,读取数据应该非常简单

var root = JsonConvert.DeserializeObject<Root>(json);

// Accessing the data
foreach (var row in root.Rows)
{
    Console.WriteLine($"Product Depth: {row.ProductInfo.Depth}, Description: {row.ProductInfo.Description}");
    foreach (var partKey in row.ProductInfo.Parts.Keys)
    {
        var part = row.ProductInfo.Parts[partKey];
        Console.WriteLine($"  Part {partKey} - Description: {part.Description}");
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.