我想根据消耗的 Json 动态创建 c# 对象。我不在乎这个json,只是想挑选我需要的属性。
我不知道是否最佳做法是使用动态关键字并根据创建的对象创建一个全新的 json 结构。
如何对嵌套对象进行去角化。示例 json:
{
'name': 'James',
'Profile': {
'body': {
'id': 'Employee1',
'type': 'Employee',
'attributes': {
props...
},
'job': {
props..
},
'team': [],
},
}
这是一个简单的尝试。
var test = JsonConvert.DeserializeObject<dynamic>(json);
Console.WriteLine(test.ToString());
我可以创建对象列表,但是当我开始父/子对象时,我似乎无法让它工作。
下面的 JSON 可以很好地作为输出:
'body': {
'id': 'Employee1',
'type': 'Employee',
'attributes': {
props...
},
'job': {
props..
},
'team': [],
}
期望的输出
{
'name': 'James',
'Profile': {
'body': {
'id': 'Employee1',
'type': 'Employee',
'attributes': {
props...
},
'job': {
props..
},
'team': [],
},
'Profile': {
'body': {
'id': 'Employee2',
'type': 'Employee',
'attributes': {
props...
},
'job': {
props..
},
'team': [],
}
}
如何反序列化嵌套对象?
您可以使用 json 类,遵循以下代码行
dynamic data = Json.Decode(json);
您可以使用JsonConvert
:
dynamic myNewObject = JsonConvert.DeserializeObject(json);
然后,您可以像这样访问 json 属性:
myNewObject.Profile.body.id
无重现。字符串已反序列化。test
包含整个图形。只要使用有效的 JSON 字符串,就会生成预期的输出:
此片段:
var json=@"{
'name': 'James',
'Profile': {
'body': {
'id': 'Employee1',
'type': 'Employee',
'attributes': {
'a':3
},
'job': {
'a':3
},
'team': [],
},
}";
var x=JsonConvert.DeserializeObject<object>(json);
Console.WriteLiine(x.ToString());
生产:
{
"name": "James",
"Profile": {
"body": {
"id": "Employee1",
"type": "Employee",
"attributes": {
"a": 3
},
"job": {
"a": 3
},
"team": []
}
}
}
不过,从评论中可以看出,实际的JSON 字符串似乎不是有效的 JSON 字符串并抛出异常:
我得到Newtonsoft.Json.JsonReaderException:"完成读取JSON内容后遇到的其他文本:,。路径",第 21 行,位置 13。
此错误指向导致问题的 JSON 字符串中的实际位置。也许那里有一个额外的角色?也许文本包含多个JSON 字符串而不是一个?以下字符串不是有效的 JSON - JSON不能有多个根对象:
{ "a":"b"}
{ "c":"d"}
日志记录工具、事件处理和分析软件虽然以这种方式为每个文件存储多个 JSON 字符串,因为它只需要一个append
操作,不需要解析整个文本来生成结果,并且使分区更容易。这仍然是无效的 JSON,尽管必须一次读取和处理一行。
许多人发现这被描述为"流式处理 JSON",正是因为您可以以流式处理方式处理数据。您可以一次加载和处理一行,而不是加载和解析 100MB 的事件文件,例如:
IEnumerable<string> lines=File.ReadLines(pathToBigFile);
foreach(var line in lines)
{
var myObject=JsonConvert.DeserializeObject<someType>(line);
//do something with that object
}
File.ReadLines
返回一个在每次迭代中仅加载一行的IEnumerable<string>
。每次只加载和分析一行,而不是加载整个 100MB 文件。