首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用具有复杂属性名称的system.text.json反序列化JSON iin C#

使用具有复杂属性名称的system.text.json反序列化JSON iin C#
EN

Stack Overflow用户
提问于 2020-02-13 00:07:30
回答 1查看 608关注 0票数 0

我正在尝试反序列化由第三方工具创建的JSON文件。

这些文件包含如下所示的属性:

代码语言:javascript
复制
"RECIPE": [{
        "ctPoint_0": {
            "endTemperature": 25,
            "hours": 0.07999999821186066,
            "startTemperature": 25
        },
        "ctPoint_1": {
            "endTemperature": 30,
            "hours": 0.07999999821186066,
            "startTemperature": 25
        },
        "ctPoint_2": {
            "endTemperature": 25,
            "hours": 0.07999999821186066,
            "startTemperature": 30
        },
        "pointCount": 3,
        "type": "CyclicTemp"
    }, {
        "cycles": 2,
        "type": "Repeat"
    }, {
        "cycles": 1,
        "duration": {
            "days": 0,
            "hours": 0
        },

    }]

我正在使用system.text.json来反序列化:

代码语言:javascript
复制
newProgram = JsonSerializer.Deserialize<Program>(jsonString, options);

我的Program类摘录:

代码语言:javascript
复制
public class Program
    {

        public IList<Recipe> RECIPE { get; set; }
    }

Recipe和cyclic_data结构:

代码语言:javascript
复制
public struct Cyclic_Data
    {
        public float endTemperature { get; set; }
        public float hours { get; set; }
        public float startTemperature { get; set; }

    }

    public struct Recipe
    {
        public int cycles { get; set; }

        // Would like to use this
        public IList<Cyclic_Data> ctPoints { get; set; }

        // this deserialises ok but obviously only to hardcoded limit
        public Cyclic_Data ctPoint_0 { get; set; }
        public Cyclic_Data ctPoint_1 { get; set; }
        public Cyclic_Data ctPoint_2 { get; set; }
        public Cyclic_Data ctPoint_3 { get; set; }
        public Cyclic_Data ctPoint_4 { get; set; }
        public Cyclic_Data ctPoint_5 { get; set; }
        public Cyclic_Data ctPoint_6 { get; set; }
        public Cyclic_Data ctPoint_7 { get; set; }
        public Cyclic_Data ctPoint_8 { get; set; }
        public Cyclic_Data ctPoint_9 { get; set; }
        public Cyclic_Data ctPoint_10 { get; set; }


        public Duration duration { get; set;}
        public string type { get; set; }
        public float temperature { get; set; }
        public int pointCount { get; set; }

    }

根据注释,如果我有许多Cyclic_Data类型的离散变量,例如ctPoint_0,那么这将成功地反序列化,然而,因为这个列表理论上可能是任意大的,所以试图声明所有可能的属性名称将是无稽之谈。

我真的很想使用IList来读取所有的ctPoint_X值,但我正在努力寻找一种方法来做到这一点。我正在研究牛顿软实现,想知道JsonProperty("name")是否可以与RegEx一起使用来解决这个问题,但我找不到任何以这种方式完成的成功示例。

我如何才能以合理的方式将其反序列化?

编辑:我目前正在寻找一个自定义的JsonNamingPolicy来重命名任何与RegEx "^ctPoint_0-9+$“匹配的属性名称为ctPoints,如果成功,请评论这是注定要失败的,或者是否有更好的方法。

编辑2:我尝试了上面概述的方法,但它不起作用,因为项目列表的正确JSON在每个项目的开头没有名称,但是这让我开始以不同的方式思考这个问题。我最终做的是在反序列化之前进行一些简单的字符串替换。这工作得很好:)

代码语言:javascript
复制
         int location;
            location = newText.IndexOf("\"ctPoint_0\":");

            newText = newText.Replace("\"ctPoint_0\":", "\"ctPoints\": [");
            if (location > 0)
            { int lastloc;

                for (int i = 1; i < 999999; i++)
                {
                    string nextString = "\"ctPoint_" + i.ToString() + "\": ";
                    lastloc = location;
                    location = newText.IndexOf(nextString);

                    newText = newText.Replace(nextString, "");
                    if (location == -1)
                    {
                        location = newText.IndexOf("}", lastloc);
                        newText = newText.Insert(location+1, "]");
                        break;
                    }
                }
               }

谢谢

EN

回答 1

Stack Overflow用户

发布于 2020-02-13 16:04:42

您可以尝试Dictionary<string, object>并在运行时检查对象类型

以下是此场景所需的模型

代码语言:javascript
复制
public class CtPoint
{
    public int endTemperature { get; set; }
    public double hours { get; set; }
    public int startTemperature { get; set; }
}

public class Duration
{
    public int days { get; set; }
    public int hours { get; set; }
}

以下是使用System.Text.Json.JsonSerializerJSON执行Deserialize操作的示例代码

代码语言:javascript
复制
var results = System.Text.Json.JsonSerializer.Deserialize<List<Dictionary<string,object>>>(json);

foreach (var model in results)
{
    foreach(var item in model)
    {
        if (item.Key.Contains("ctPoint"))
        {
            var ctPoint = System.Text.Json.JsonSerializer.Deserialize<CtPoint>(item.Value.ToString());
            Console.WriteLine($"{item.Key}- {ctPoint.hours} {ctPoint.startTemperature} {ctPoint.endTemperature}");
        }
        else if (item.Key.Contains("duration"))
        {
            var duration = System.Text.Json.JsonSerializer.Deserialize<Duration>(item.Value.ToString());
            Console.WriteLine($"{item.Key}- {duration.days} {duration.hours}");
        }
        else
        {
            Console.WriteLine($"{item.Key}- {item.Value.ToString()}");
        }
    }
}

输出

代码语言:javascript
复制
ctPoint_0- 0,0799999982118607 25 25
ctPoint_1- 0,0799999982118607 25 30
ctPoint_2- 0,0799999982118607 30 25
pointCount- 3
type- CyclicTemp
cycles- 2
type- Repeat
cycles- 1
duration- 0 0
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60192534

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档