如何反序列化复杂 JSON 并将其创建为 C# 对象
How to Deserialize complex JSON and create it as C# Object
我有一个 JSON 如下所示:
{
"Values": [
{
"MsgSource": null,
"TagName": "Data.New_MSG",
"RawValue": "[\r\n {\r\n \"ID\": 145,\r\n \"StationNo\": 6,\r\n \"RunTime\": 1800,\r\n \"ControllerID\": 4,\r\n \"ControllerAddress\": 2,\r\n \"ProgramNo\": 2,\r\n \"ModeID\": \"AutoProgram\",\r\n \"EventDate\": \"2022-04-27T23:30:02\",\r\n \"Description\": \"Irrigation Completed\",\r\n \"MessageCode\": 5\r\n },\r\n {\r\n \"ID\": 144,\r\n \"StationNo\": 18,\r\n \"RunTime\": 1800,\r\n \"ControllerID\": 4,\r\n \"ControllerAddress\": 2,\r\n \"ProgramNo\": 5,\r\n \"ModeID\": \"AutoProgram\",\r\n \"EventDate\": \"2022-04-27T22:00:00\",\r\n \"Description\": \"Irrigation Completed\",\r\n \"MessageCode\": 5\r\n },\r\n {\r\n \"ID\": 143,\r\n \"StationNo\": 15,\r\n \"RunTime\": 1800,\r\n \"ControllerID\": 4,\r\n \"ControllerAddress\": 2,\r\n \"ProgramNo\": 4,\r\n \"ModeID\": \"AutoProgram\",\r\n \"EventDate\": \"2022-04-27T22:00:02\",\r\n \"Description\": \"Irrigation Completed\",\r\n \"MessageCode\": 5\r\n },\r\n {\r\n \"ID\": 142,\r\n \"StationNo\": 19,\r\n \"RunTime\": 1800,\r\n \"ControllerID\": 4,\r\n \"ControllerAddress\": 2,\r\n \"ProgramNo\": 5,\r\n \"ModeID\": \"AutoProgram\",\r\n \"EventDate\": \"2022-04-27T22:30:02\",\r\n \"Description\": \"Irrigation Completed\",\r\n \"MessageCode\": 5\r\n }\r\n]",
"ScaledValue": "[\r\n {\r\n \"ID\": 145,\r\n \"StationNo\": 6,\r\n \"RunTime\": 1800,\r\n \"ControllerID\": 4,\r\n \"ControllerAddress\": 2,\r\n \"ProgramNo\": 2,\r\n \"ModeID\": \"AutoProgram\",\r\n \"EventDate\": \"2022-04-27T23:30:02\",\r\n \"Description\": \"Irrigation Completed\",\r\n \"MessageCode\": 5\r\n },\r\n {\r\n \"ID\": 144,\r\n \"StationNo\": 18,\r\n \"RunTime\": 1800,\r\n \"ControllerID\": 4,\r\n \"ControllerAddress\": 2,\r\n \"ProgramNo\": 5,\r\n \"ModeID\": \"AutoProgram\",\r\n \"EventDate\": \"2022-04-27T22:00:00\",\r\n \"Description\": \"Irrigation Completed\",\r\n \"MessageCode\": 5\r\n },\r\n {\r\n \"ID\": 143,\r\n \"StationNo\": 15,\r\n \"RunTime\": 1800,\r\n \"ControllerID\": 4,\r\n \"ControllerAddress\": 2,\r\n \"ProgramNo\": 4,\r\n \"ModeID\": \"AutoProgram\",\r\n \"EventDate\": \"2022-04-27T22:00:02\",\r\n \"Description\": \"Irrigation Completed\",\r\n \"MessageCode\": 5\r\n },\r\n {\r\n \"ID\": 142,\r\n \"StationNo\": 19,\r\n \"RunTime\": 1800,\r\n \"ControllerID\": 4,\r\n \"ControllerAddress\": 2,\r\n \"ProgramNo\": 5,\r\n \"ModeID\": \"AutoProgram\",\r\n \"EventDate\": \"2022-04-27T22:30:02\",\r\n \"Description\": \"Irrigation Completed\",\r\n \"MessageCode\": 5\r\n }\r\n]",
"Status": "Normal",
"ComStatus": null,
"TimeStamp": "2022-04-28 13:17:39.851"
}
]
}
如何反序列化此 JSON 并创建一个仅包含 RawValue 内部值的列表,其中其中的每个有效负载都将作为列表中的单个元素。还有如何从列表中的每个元素中删除不需要的 \r\n 和转义字符。
你有 JSON 包含 JSON,基本上 - 所以你应该 期望 必须反序列化一次。 (诚然,如果您可以更改 JSON 的结构来避免这种 double-serialization,那会更好,但我会假设它是固定的。)
例如,您可以:
public class Root
{
public List<Value> Values { get; set; }
}
public class Value
{
// Add other properties if you need them
public string RawValue { get; set; }
}
然后:
string json = ...;
Root root = JsonConvert.DeserializeObject<Root>(json);
// This just takes the first value - we don't know whether you actually
// ever have more than one...
string rawValue = root.Values[0].RawValue;
JArray array = JArray.Parse(rawValue);
假定您乐于使用 JArray
/JObject
作为“嵌入式”对象。如果你也想对它们进行建模,你需要:
public class Station
{
[JsonProperty("ID")]
public int Id { get; set; }
public int StationNo { get; set; }
// etc
}
...然后进行反序列化:
string json = ...;
Root root = JsonConvert.DeserializeObject<Root>(json);
// This just takes the first value - we don't know whether you actually
// ever have more than one...
string rawValue = root.Values[0].RawValue;
List<Station> stations = JsonConvert.DeserializeObject<List<Station>>(rawValue);
当你反序列化两次时,不应该有任何“额外”转义。
试试这个
List<RawValue> rawValue= JsonConvert.DeserializeObject<List<RawValue>>(
(string) JObject.Parse(json)["Values"]
.SelectMany(x =>((JObject) x).Properties()
.Where(x=>x.Name=="RawValue")).First()
.Value);
结果(采用 json 格式)
[{"ID":145,"StationNo":6,"RunTime":1800,"ControllerID":4,"ControllerAddress":2,"ProgramNo":2,"ModeID":"AutoProgram","EventDate":"2022-04-27T23:30:02","Description":"Irrigation Completed","MessageCode":5},
{"ID":144,"StationNo":18,"RunTime":1800,"ControllerID":4,"ControllerAddress":2,"ProgramNo":5,"ModeID":"AutoProgram","EventDate":"2022-04-27T22:00:00","Description":"Irrigation Completed","MessageCode":5},
{"ID":143,"StationNo":15,"RunTime":1800,"ControllerID":4,"ControllerAddress":2,"ProgramNo":4,"ModeID":"AutoProgram","EventDate":"2022-04-27T22:00:02","Description":"Irrigation Completed","MessageCode":5},
{"ID":142,"StationNo":19,"RunTime":1800,"ControllerID":4,"ControllerAddress":2,"ProgramNo":5,"ModeID":"AutoProgram","EventDate":"2022-04-27T22:30:02","Description":"Irrigation Completed","MessageCode":5}]
class
public class RawValue
{
public int ID { get; set; }
public int StationNo { get; set; }
public int RunTime { get; set; }
public int ControllerID { get; set; }
public int ControllerAddress { get; set; }
public int ProgramNo { get; set; }
public string ModeID { get; set; }
public DateTime EventDate { get; set; }
public string Description { get; set; }
public int MessageCode { get; set; }
}
我有一个 JSON 如下所示:
{
"Values": [
{
"MsgSource": null,
"TagName": "Data.New_MSG",
"RawValue": "[\r\n {\r\n \"ID\": 145,\r\n \"StationNo\": 6,\r\n \"RunTime\": 1800,\r\n \"ControllerID\": 4,\r\n \"ControllerAddress\": 2,\r\n \"ProgramNo\": 2,\r\n \"ModeID\": \"AutoProgram\",\r\n \"EventDate\": \"2022-04-27T23:30:02\",\r\n \"Description\": \"Irrigation Completed\",\r\n \"MessageCode\": 5\r\n },\r\n {\r\n \"ID\": 144,\r\n \"StationNo\": 18,\r\n \"RunTime\": 1800,\r\n \"ControllerID\": 4,\r\n \"ControllerAddress\": 2,\r\n \"ProgramNo\": 5,\r\n \"ModeID\": \"AutoProgram\",\r\n \"EventDate\": \"2022-04-27T22:00:00\",\r\n \"Description\": \"Irrigation Completed\",\r\n \"MessageCode\": 5\r\n },\r\n {\r\n \"ID\": 143,\r\n \"StationNo\": 15,\r\n \"RunTime\": 1800,\r\n \"ControllerID\": 4,\r\n \"ControllerAddress\": 2,\r\n \"ProgramNo\": 4,\r\n \"ModeID\": \"AutoProgram\",\r\n \"EventDate\": \"2022-04-27T22:00:02\",\r\n \"Description\": \"Irrigation Completed\",\r\n \"MessageCode\": 5\r\n },\r\n {\r\n \"ID\": 142,\r\n \"StationNo\": 19,\r\n \"RunTime\": 1800,\r\n \"ControllerID\": 4,\r\n \"ControllerAddress\": 2,\r\n \"ProgramNo\": 5,\r\n \"ModeID\": \"AutoProgram\",\r\n \"EventDate\": \"2022-04-27T22:30:02\",\r\n \"Description\": \"Irrigation Completed\",\r\n \"MessageCode\": 5\r\n }\r\n]",
"ScaledValue": "[\r\n {\r\n \"ID\": 145,\r\n \"StationNo\": 6,\r\n \"RunTime\": 1800,\r\n \"ControllerID\": 4,\r\n \"ControllerAddress\": 2,\r\n \"ProgramNo\": 2,\r\n \"ModeID\": \"AutoProgram\",\r\n \"EventDate\": \"2022-04-27T23:30:02\",\r\n \"Description\": \"Irrigation Completed\",\r\n \"MessageCode\": 5\r\n },\r\n {\r\n \"ID\": 144,\r\n \"StationNo\": 18,\r\n \"RunTime\": 1800,\r\n \"ControllerID\": 4,\r\n \"ControllerAddress\": 2,\r\n \"ProgramNo\": 5,\r\n \"ModeID\": \"AutoProgram\",\r\n \"EventDate\": \"2022-04-27T22:00:00\",\r\n \"Description\": \"Irrigation Completed\",\r\n \"MessageCode\": 5\r\n },\r\n {\r\n \"ID\": 143,\r\n \"StationNo\": 15,\r\n \"RunTime\": 1800,\r\n \"ControllerID\": 4,\r\n \"ControllerAddress\": 2,\r\n \"ProgramNo\": 4,\r\n \"ModeID\": \"AutoProgram\",\r\n \"EventDate\": \"2022-04-27T22:00:02\",\r\n \"Description\": \"Irrigation Completed\",\r\n \"MessageCode\": 5\r\n },\r\n {\r\n \"ID\": 142,\r\n \"StationNo\": 19,\r\n \"RunTime\": 1800,\r\n \"ControllerID\": 4,\r\n \"ControllerAddress\": 2,\r\n \"ProgramNo\": 5,\r\n \"ModeID\": \"AutoProgram\",\r\n \"EventDate\": \"2022-04-27T22:30:02\",\r\n \"Description\": \"Irrigation Completed\",\r\n \"MessageCode\": 5\r\n }\r\n]",
"Status": "Normal",
"ComStatus": null,
"TimeStamp": "2022-04-28 13:17:39.851"
}
]
}
如何反序列化此 JSON 并创建一个仅包含 RawValue 内部值的列表,其中其中的每个有效负载都将作为列表中的单个元素。还有如何从列表中的每个元素中删除不需要的 \r\n 和转义字符。
你有 JSON 包含 JSON,基本上 - 所以你应该 期望 必须反序列化一次。 (诚然,如果您可以更改 JSON 的结构来避免这种 double-serialization,那会更好,但我会假设它是固定的。)
例如,您可以:
public class Root
{
public List<Value> Values { get; set; }
}
public class Value
{
// Add other properties if you need them
public string RawValue { get; set; }
}
然后:
string json = ...;
Root root = JsonConvert.DeserializeObject<Root>(json);
// This just takes the first value - we don't know whether you actually
// ever have more than one...
string rawValue = root.Values[0].RawValue;
JArray array = JArray.Parse(rawValue);
假定您乐于使用 JArray
/JObject
作为“嵌入式”对象。如果你也想对它们进行建模,你需要:
public class Station
{
[JsonProperty("ID")]
public int Id { get; set; }
public int StationNo { get; set; }
// etc
}
...然后进行反序列化:
string json = ...;
Root root = JsonConvert.DeserializeObject<Root>(json);
// This just takes the first value - we don't know whether you actually
// ever have more than one...
string rawValue = root.Values[0].RawValue;
List<Station> stations = JsonConvert.DeserializeObject<List<Station>>(rawValue);
当你反序列化两次时,不应该有任何“额外”转义。
试试这个
List<RawValue> rawValue= JsonConvert.DeserializeObject<List<RawValue>>(
(string) JObject.Parse(json)["Values"]
.SelectMany(x =>((JObject) x).Properties()
.Where(x=>x.Name=="RawValue")).First()
.Value);
结果(采用 json 格式)
[{"ID":145,"StationNo":6,"RunTime":1800,"ControllerID":4,"ControllerAddress":2,"ProgramNo":2,"ModeID":"AutoProgram","EventDate":"2022-04-27T23:30:02","Description":"Irrigation Completed","MessageCode":5},
{"ID":144,"StationNo":18,"RunTime":1800,"ControllerID":4,"ControllerAddress":2,"ProgramNo":5,"ModeID":"AutoProgram","EventDate":"2022-04-27T22:00:00","Description":"Irrigation Completed","MessageCode":5},
{"ID":143,"StationNo":15,"RunTime":1800,"ControllerID":4,"ControllerAddress":2,"ProgramNo":4,"ModeID":"AutoProgram","EventDate":"2022-04-27T22:00:02","Description":"Irrigation Completed","MessageCode":5},
{"ID":142,"StationNo":19,"RunTime":1800,"ControllerID":4,"ControllerAddress":2,"ProgramNo":5,"ModeID":"AutoProgram","EventDate":"2022-04-27T22:30:02","Description":"Irrigation Completed","MessageCode":5}]
class
public class RawValue
{
public int ID { get; set; }
public int StationNo { get; set; }
public int RunTime { get; set; }
public int ControllerID { get; set; }
public int ControllerAddress { get; set; }
public int ProgramNo { get; set; }
public string ModeID { get; set; }
public DateTime EventDate { get; set; }
public string Description { get; set; }
public int MessageCode { get; set; }
}