Mat*_*cic 6 c# json json.net deserialization
使用JSON.NET进行反序列化时,我遇到以下JSON问题.
{
"?xml": {
"@version": "1.0",
"@encoding": "utf-8"
},
"Persons": {
"Person": [{
"@Id": "1",
"@Name": "John",
"@Surname": "Smith"
},
{
"@Id": "2",
"@Name": "John",
"@Surname": "Smith",
"Skills": {
"Skill": [{
"@Id": "1",
"@Name": "Developer"
},
{
"@Id": "2",
"@Name": "Tester"
}]
}
}]
}
}
Run Code Online (Sandbox Code Playgroud)
我正在使用以下课程:
public class RootObject
{
public Xml xml { get; set; }
public Persons Persons { get; set; }
}
public class Xml
{
public string version { get; set; }
public string encoding { get; set; }
}
public class Persons
{
public List<Person> Person { get; set; }
}
public class Skill
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Skills
{
public List<Skill> Skill { get; set; }
}
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public Skills Skills { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
当我尝试反序列化时
RootObject persons = JsonConvert.DeserializeObject<RootObject>(json);
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
无法将当前JSON对象(例如{"name":"value"})反序列化为类型'System.Collections.Generic.List`1 [Project.Models.Persons.Skill]',因为该类型需要JSON数组(例如[ 1,2,3])正确反序列化.要修复此错误,请将JSON更改为JSON数组(例如[1,2,3])或更改反序列化类型,使其成为普通的.NET类型(例如,不是像整数这样的基本类型,而不是类似的集合类型可以从JSON对象反序列化的数组或List.JsonObjectAttribute也可以添加到类型中以强制它从JSON对象反序列化.
我想问题在于符号:
"Skills": {
"Skill": [{
Run Code Online (Sandbox Code Playgroud)
我错过了什么,这个问题有一个简单的解决方案吗?
更新:
所以最后问题是它有时候是一个JSON数组
"Skills": {
"Skill": [{
Run Code Online (Sandbox Code Playgroud)
有时候是一个JSON对象
"Skills": {
"Skill": {
Run Code Online (Sandbox Code Playgroud)
但是当我将代码粘贴/检查到验证器时,它总是被格式化为JSON数组,所以我使用监视窗口检查它以查看原始json字符串.
从那里可以很容易地用JsonConverter属性标记属性
public class Skills
{
[JsonConverter(typeof(MyConverter))]
public List<Skill> Skill { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
并写入转换器:
public class MyConverter : JsonConverter
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.StartArray)
{
return serializer.Deserialize<List<Skill>>(reader);
}
else
{
Skill skill = serializer.Deserialize<Skill>(reader);
return new List<Skill>(new[] { skill});
}
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue(value);
}
}
Run Code Online (Sandbox Code Playgroud)
希望它对某人有帮助.
我认为,使用您当前的 JSON,您正在描述Skill包含一个集合,而不是Skills. 试试这个 JSON:
"Skills": [
{
"@Id": "1",
"@Name": "Developer"
},
{
"@Id": "2",
"@Name": "Tester"
}
]
Run Code Online (Sandbox Code Playgroud)
同样的事情也适用于定义集合的方式Persons。
编辑:
这个测试对我来说通过了:
[TestFixture]
public class JSONTester
{
[Test]
public void Json_deserialize()
{
var json = @"{
""?xml"": {
""@version"": ""1.0"",
""@encoding"": ""utf-8""
},
""Persons"": {
""Person"": [{
""@Id"": ""1"",
""@Name"": ""John"",
""@Surname"": ""Smith""
},
{
""@Id"": ""2"",
""@Name"": ""John"",
""@Surname"": ""Smith"",
""Skills"": {
""Skill"": [{
""@Id"": ""1"",
""@Name"": ""Developer""
},
{
""@Id"": ""2"",
""@Name"": ""Tester""
}]
}
}]
}
}";
var persons = JsonConvert.DeserializeObject<RootObject>(json);
Assert.AreEqual(persons.Persons.Person[1].Skills.Skill.Count, 2);
}
public class RootObject
{
public Xml xml { get; set; }
public Persons Persons { get; set; }
}
public class Xml
{
public string version { get; set; }
public string encoding { get; set; }
}
public class Persons
{
public List<Person> Person { get; set; }
}
public class Skill
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Skills
{
public List<Skill> Skill { get; set; }
}
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public Skills Skills { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)