如何在 C# 中使用嵌套动态键数组反序列化 json
How to deserialize json with nest array of dynamic keys in C#
我有以下 json 来自 api return 的结构:
{
"firstName": "test first",
"lastName": "test last",
"moduleReports": [
{
"completion": "Nothing shared",
"thoughts": "example",
"componentTitle": "CareerCorner"
},
{
"thoughts": "example",
"componentTitle": "CareerLIbrary"
},
{
"completionDate": "0001-01-01T00:00:00",
"componentTitle": "Discoverer"
},
{
"completionDate": "0001-01-01T00:00:00",
"componentTitle": "Explorer"
},
{
"workValues": [
"independence",
"relationships"
],
"componentTitle": "Navigator"
},
{
"personalityTypes": [
"Creator",
"Doer"
],
"componentTitle": "Pathfinder"
},
{
"reflection": "example",
"completionDate": "0001-01-01T00:00:00",
"componentTitle": "QuickPic"
},
{
"careerGroup": "Ideas",
"componentTitle": "Scout"
},
{
"improveAtSkills": [
"listen",
"speak"
],
"goodAtSkills": [
"decision",
"solve"
],
"componentTitle": "Trekker"
}
]
}
我尝试自己创建 类 并想出了
public class ModuleReport
{
public string completion { get; set; }
public string thoughts { get; set; }
public string componentTitle { get; set; }
public DateTime? completionDate { get; set; }
public List<string> workValues { get; set; }
public List<string> personalityTypes { get; set; }
public string reflection { get; set; }
public string careerGroup { get; set; }
public List<string> improveAtSkills { get; set; }
public List<string> goodAtSkills { get; set; }
}
public class ModuleResult
{
public string firstName { get; set; }
public string lastName { get; set; }
public List<ModuleReport> moduleReports { get; set; }
}
但是当我打电话时
var mResults = JsonConvert.DeserializeObject<List<ModuleResult>>( jsonString );
在控制器中我得到以下错误
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[...Reports.User.ModuleResults]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
我已尝试按照此处答案中的建议进行操作: and here 但我总是遇到同样的错误。
我开始构建以下内容
public override object ReadJson( JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer )
{
var responseObject = JObject.Load( reader );
ModuleResult response = new ModuleResult
{
firstName = (string)responseObject[ "firstName" ],
lastName = (string)responseObject[ "lastName" ],
};
var varData = new Dictionary<string, object>();
foreach ( var property in responseObject.Properties() )
{
if ( property.Name == "firstName" || property.Name == "lastName" )
{
continue;
}
varData.Add( property.Name, property.Value );
}
response.VarData = varData;
return response;
}
但是当我把它放到位时,我意识到它只会将整个“moduleResults”节点添加为
键及其所有内容作为值。回到第一个问题。
我知道问题是访问“moduleReports”json 数组并正确反序列化那些 key/value 对,但我有一段时间想弄清楚如何深入研究它嵌套数组,然后如何处理不断变化的 key/value 对。
当您提供的 JSON 结构表明它是单个 ModuleResult
对象时,为什么要将其反序列化为 List<ModuleResult>
?
改变一下
var mResults = JsonConvert.DeserializeObject<List<ModuleResult>>( jsonString );
到
var mResults = JsonConvert.DeserializeObject<ModuleResult>( jsonString );
它会被正确反序列化。
试试这个
var jD = JsonConvert.DeserializeObject<Root>(json);
output=JsonConvert.SerializeObject(jD);
输出
{"firstName":"test first","lastName":"test last","moduleReports":[{"completion":"Nothing shared","thoughts":"example","componentTitle":"CareerCorner"},{"thoughts":"example","componentTitle":"CareerLIbrary"},{"componentTitle":"Discoverer","completionDate":"0001-01-01T00:00:00-03:30"},{"componentTitle":"Explorer","completionDate":"0001-01-01T00:00:00-03:30"},{"componentTitle":"Navigator","workValues":["independence","relationships"]},{"componentTitle":"Pathfinder","personalityTypes":["Creator","Doer"]},{"componentTitle":"QuickPic","completionDate":"0001-01-01T00:00:00-03:30","reflection":"example"},{"componentTitle":"Scout","careerGroup":"Ideas"},{"componentTitle":"Trekker","improveAtSkills":["listen","speak"],"goodAtSkills":["decision","solve"]}]}
类
public partial class Root
{
[JsonProperty("firstName")]
public string FirstName { get; set; }
[JsonProperty("lastName")]
public string LastName { get; set; }
[JsonProperty("moduleReports")]
public ModuleReport[] ModuleReports { get; set; }
}
public partial class ModuleReport
{
[JsonProperty("completion", NullValueHandling = NullValueHandling.Ignore)]
public string Completion { get; set; }
[JsonProperty("thoughts", NullValueHandling = NullValueHandling.Ignore)]
public string Thoughts { get; set; }
[JsonProperty("componentTitle")]
public string ComponentTitle { get; set; }
[JsonProperty("completionDate", NullValueHandling = NullValueHandling.Ignore)]
public DateTimeOffset? CompletionDate { get; set; }
[JsonProperty("workValues", NullValueHandling = NullValueHandling.Ignore)]
public string[] WorkValues { get; set; }
[JsonProperty("personalityTypes", NullValueHandling = NullValueHandling.Ignore)]
public string[] PersonalityTypes { get; set; }
[JsonProperty("reflection", NullValueHandling = NullValueHandling.Ignore)]
public string Reflection { get; set; }
[JsonProperty("careerGroup", NullValueHandling = NullValueHandling.Ignore)]
public string CareerGroup { get; set; }
[JsonProperty("improveAtSkills", NullValueHandling = NullValueHandling.Ignore)]
public string[] ImproveAtSkills { get; set; }
[JsonProperty("goodAtSkills", NullValueHandling = NullValueHandling.Ignore)]
public string[] GoodAtSkills { get; set; }
}
我有以下 json 来自 api return 的结构:
{
"firstName": "test first",
"lastName": "test last",
"moduleReports": [
{
"completion": "Nothing shared",
"thoughts": "example",
"componentTitle": "CareerCorner"
},
{
"thoughts": "example",
"componentTitle": "CareerLIbrary"
},
{
"completionDate": "0001-01-01T00:00:00",
"componentTitle": "Discoverer"
},
{
"completionDate": "0001-01-01T00:00:00",
"componentTitle": "Explorer"
},
{
"workValues": [
"independence",
"relationships"
],
"componentTitle": "Navigator"
},
{
"personalityTypes": [
"Creator",
"Doer"
],
"componentTitle": "Pathfinder"
},
{
"reflection": "example",
"completionDate": "0001-01-01T00:00:00",
"componentTitle": "QuickPic"
},
{
"careerGroup": "Ideas",
"componentTitle": "Scout"
},
{
"improveAtSkills": [
"listen",
"speak"
],
"goodAtSkills": [
"decision",
"solve"
],
"componentTitle": "Trekker"
}
]
}
我尝试自己创建 类 并想出了
public class ModuleReport
{
public string completion { get; set; }
public string thoughts { get; set; }
public string componentTitle { get; set; }
public DateTime? completionDate { get; set; }
public List<string> workValues { get; set; }
public List<string> personalityTypes { get; set; }
public string reflection { get; set; }
public string careerGroup { get; set; }
public List<string> improveAtSkills { get; set; }
public List<string> goodAtSkills { get; set; }
}
public class ModuleResult
{
public string firstName { get; set; }
public string lastName { get; set; }
public List<ModuleReport> moduleReports { get; set; }
}
但是当我打电话时
var mResults = JsonConvert.DeserializeObject<List<ModuleResult>>( jsonString );
在控制器中我得到以下错误
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[...Reports.User.ModuleResults]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
我已尝试按照此处答案中的建议进行操作:
我开始构建以下内容
public override object ReadJson( JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer )
{
var responseObject = JObject.Load( reader );
ModuleResult response = new ModuleResult
{
firstName = (string)responseObject[ "firstName" ],
lastName = (string)responseObject[ "lastName" ],
};
var varData = new Dictionary<string, object>();
foreach ( var property in responseObject.Properties() )
{
if ( property.Name == "firstName" || property.Name == "lastName" )
{
continue;
}
varData.Add( property.Name, property.Value );
}
response.VarData = varData;
return response;
}
但是当我把它放到位时,我意识到它只会将整个“moduleResults”节点添加为 键及其所有内容作为值。回到第一个问题。
我知道问题是访问“moduleReports”json 数组并正确反序列化那些 key/value 对,但我有一段时间想弄清楚如何深入研究它嵌套数组,然后如何处理不断变化的 key/value 对。
当您提供的 JSON 结构表明它是单个 ModuleResult
对象时,为什么要将其反序列化为 List<ModuleResult>
?
改变一下
var mResults = JsonConvert.DeserializeObject<List<ModuleResult>>( jsonString );
到
var mResults = JsonConvert.DeserializeObject<ModuleResult>( jsonString );
它会被正确反序列化。
试试这个
var jD = JsonConvert.DeserializeObject<Root>(json);
output=JsonConvert.SerializeObject(jD);
输出
{"firstName":"test first","lastName":"test last","moduleReports":[{"completion":"Nothing shared","thoughts":"example","componentTitle":"CareerCorner"},{"thoughts":"example","componentTitle":"CareerLIbrary"},{"componentTitle":"Discoverer","completionDate":"0001-01-01T00:00:00-03:30"},{"componentTitle":"Explorer","completionDate":"0001-01-01T00:00:00-03:30"},{"componentTitle":"Navigator","workValues":["independence","relationships"]},{"componentTitle":"Pathfinder","personalityTypes":["Creator","Doer"]},{"componentTitle":"QuickPic","completionDate":"0001-01-01T00:00:00-03:30","reflection":"example"},{"componentTitle":"Scout","careerGroup":"Ideas"},{"componentTitle":"Trekker","improveAtSkills":["listen","speak"],"goodAtSkills":["decision","solve"]}]}
类
public partial class Root
{
[JsonProperty("firstName")]
public string FirstName { get; set; }
[JsonProperty("lastName")]
public string LastName { get; set; }
[JsonProperty("moduleReports")]
public ModuleReport[] ModuleReports { get; set; }
}
public partial class ModuleReport
{
[JsonProperty("completion", NullValueHandling = NullValueHandling.Ignore)]
public string Completion { get; set; }
[JsonProperty("thoughts", NullValueHandling = NullValueHandling.Ignore)]
public string Thoughts { get; set; }
[JsonProperty("componentTitle")]
public string ComponentTitle { get; set; }
[JsonProperty("completionDate", NullValueHandling = NullValueHandling.Ignore)]
public DateTimeOffset? CompletionDate { get; set; }
[JsonProperty("workValues", NullValueHandling = NullValueHandling.Ignore)]
public string[] WorkValues { get; set; }
[JsonProperty("personalityTypes", NullValueHandling = NullValueHandling.Ignore)]
public string[] PersonalityTypes { get; set; }
[JsonProperty("reflection", NullValueHandling = NullValueHandling.Ignore)]
public string Reflection { get; set; }
[JsonProperty("careerGroup", NullValueHandling = NullValueHandling.Ignore)]
public string CareerGroup { get; set; }
[JsonProperty("improveAtSkills", NullValueHandling = NullValueHandling.Ignore)]
public string[] ImproveAtSkills { get; set; }
[JsonProperty("goodAtSkills", NullValueHandling = NullValueHandling.Ignore)]
public string[] GoodAtSkills { get; set; }
}