【C#】复杂Json的反序列
复杂结构的JSON
如何将一个复杂类型的JSON进行反序列化。那就是如何把json拆解成一个个子类的过程。
如下我有这样一个json字符串:
{
"success": True,
"message": "操作成功!",
"code": 200,
"result": {
"ruleColumn": [
{
"columnChName": "孔宽1"
},
{
"columnChName": "孔从中心偏移3"
},
{
"columnChName": "孔从中心偏移6"
},
{
"columnChName": "孔从中心偏移5"
},
{
"columnChName": "孔从中心偏移2"
},
{
"columnChName": "孔长3"
},
{
"columnChName": "孔从中心偏移7"
},
{
"columnChName": "孔从中心偏移4"
},
{
"columnChName": "孔中到Y中心8"
},
{
"columnChName": "孔中到X中心9"
}
],
"number": 5,
"titleColumn": [
{
"columnChName": "工序",
"columnType": "input",
"selectValue": None
},
{
"columnChName": "日期",
"columnType": "date",
"selectValue": None
},
{
"columnChName": "班次",
"columnType": "select",
"selectValue": [
"A",
"B"
]
},
{
"columnChName": "测试时间",
"columnType": "input",
"selectValue": None
},
{
"columnChName": "测试员",
"columnType": "input",
"selectValue": None
},
{
"columnChName": "测试机台号",
"columnType": "input",
"selectValue": None
},
{
"columnChName": "备注",
"columnType": "input",
"selectValue": None
},
{
"columnChName": "生产机台",
"columnType": "input",
"selectValue": None
},
{
"columnChName": "检验方式",
"columnType": "input",
"selectValue": None
},
{
"columnChName": "判定",
"columnType": "judge",
"selectValue": None
}
],
"projectDetailId": "1559817674652483586",
"rules": [
{
"columnChName": "孔宽1",
"nominalDim": 17.28,
"tolMax": 0.02,
"tolMin": 0.02,
"usl": 17.3,
"lsl": 17.26
},
{
"columnChName": "孔从中心偏移3",
"nominalDim": 17.28,
"tolMax": 0.02,
"tolMin": 0.02,
"usl": 17.3,
"lsl": 17.26
},
{
"columnChName": "孔从中心偏移6",
"nominalDim": 17.28,
"tolMax": 0.02,
"tolMin": 0.02,
"usl": 17.3,
"lsl": 17.26
},
{
"columnChName": "孔从中心偏移5",
"nominalDim": 13.84,
"tolMax": 0.05,
"tolMin": 0.05,
"usl": 13.89,
"lsl": 13.79
},
{
"columnChName": "孔从中心偏移2",
"nominalDim": 13.84,
"tolMax": 0.05,
"tolMin": 0.05,
"usl": 13.89,
"lsl": 13.79
},
{
"columnChName": "孔长3",
"nominalDim": 52.94,
"tolMax": 0.02,
"tolMin": 0.02,
"usl": 52.96,
"lsl": 52.92
},
{
"columnChName": "孔从中心偏移7",
"nominalDim": 49.75,
"tolMax": 0.02,
"tolMin": 0.02,
"usl": 49.77,
"lsl": 49.73
},
{
"columnChName": "孔从中心偏移4",
"nominalDim": 49.75,
"tolMax": 0.02,
"tolMin": 0.02,
"usl": 49.77,
"lsl": 49.73
},
{
"columnChName": "孔中到Y中心8",
"nominalDim": 43.99,
"tolMax": 0.02,
"tolMin": 0.02,
"usl": 44.01,
"lsl": 43.97
},
{
"columnChName": "孔中到X中心9",
"nominalDim": 16.23,
"tolMax": 0.02,
"tolMin": 0.02,
"usl": 16.25,
"lsl": 16.21
}
]
},
"timestamp": 1663056576303
}
其中result这个key对应的内容是可能发生变化的,所以这里可以用到泛型。大体不变的框架是这样的:
{
"success": True,
"message": "添加成功!",
"code": 200,
"result": None,
"timestamp": int(round(time.time() * 1000))
}
类的构造
那我先构造这个类,对于大的框架:
注意,类名并不重要(他代表的是大括号)重要的是属性的名称,需要和key的值保持一致:
public class WeiDaLiResult<T>
{
public bool success { get; set; }
public string message { get; set; }
public int code { get; set; }
public T result { get; set; }
public ulong timestamp { get; set; }
}
然后是针对当前result的部分,这里的技术关键是如何构造json数组,我们用到了IList接口:
#region item 项
public class RuleColumnItem
{
public string columnChName { get; set; }
}
public class TitleColumnItem
{
public string columnChName { get; set; }
public string columnType { get; set; }
public IList<string> selectValue { get; set; }
}
public class RulesItem
{
public string columnChName { get; set; }
public float nominalDim { get; set; }
public float tolMax { get; set; }
public float tolMin { get; set; }
public float usl { get; set; }
public float lsl { get; set; }
}
#endregion
public class SubResult
{
public IList<RuleColumnItem> ruleColumn { get; set; }
public int number { get; set; }
public IList<TitleColumnItem> titleColumn { get; set; }
public string projectDetailId { get; set; }
public IList<RulesItem> rules { get; set; }
}
反序列化过程调用
反序列化过程调用(注意泛型是如何被使用的):
var r = System.Text.Json.JsonSerializer.Deserialize<WeiDaLiResult<SubResult>>(str_json);
枚举的反序列化
这里在做一个优化:
将columnType这个字段序列化成枚举。
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum ControlType
{
input = 0,
date,
select,
judge,
}
类改造
//改造前
public class TitleColumnItem
{
public string columnChName { get; set; }
public string columnType { get; set; }
public IList<string> selectValue { get; set; }
}
//改造后
public class TitleColumnItem
{
public string columnChName { get; set; }
public ControlType columnType { get; set; }
public IList<string> selectValue { get; set; }
}
注意,枚举要序列化,需要加一个特性:
[JsonConverter(typeof(JsonStringEnumConverter))]
补充
本文用到的Json库是:
以前用这个
现在微软主推上面这个。