我正在尝试反序列化由第三方工具创建的JSON文件。
这些文件包含如下所示的属性:
"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来反序列化:
newProgram = JsonSerializer.Deserialize<Program>(jsonString, options);我的Program类摘录:
public class Program
{
public IList<Recipe> RECIPE { get; set; }
}Recipe和cyclic_data结构:
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在每个项目的开头没有名称,但是这让我开始以不同的方式思考这个问题。我最终做的是在反序列化之前进行一些简单的字符串替换。这工作得很好:)
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;
}
}
}谢谢
发布于 2020-02-13 16:04:42
您可以尝试Dictionary<string, object>并在运行时检查对象类型
以下是此场景所需的模型
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.JsonSerializer对JSON执行Deserialize操作的示例代码
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()}");
}
}
}输出
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 0https://stackoverflow.com/questions/60192534
复制相似问题