C# 反序列化JSON不使用JSON.NET

C# 反序列化JSON不使用JSON.NET,c#,json,json.net,deserialization,C#,Json,Json.net,Deserialization,在使用JSON.NET进行反序列化时,我遇到了以下JSON问题 { "?xml": { "@version": "1.0", "@encoding": "utf-8" }, "Persons": { "Person": [{ "@Id": "1", "@Name": "John", "@Surname": "Smith"

在使用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"
                }]
            }
        }]
    }
}
我正在使用以下类:

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; }
}
我遗漏了什么,这个问题有没有简单的解决办法

更新:

所以最后的问题是它有时是一个JSON数组

"Skills": {
                "Skill": [{
有时是JSON对象

"Skills": {
                "Skill": {
但是,当将我的代码粘贴/检查到验证器中时,它总是被格式化为JSON数组,因此我使用watch window检查了它,以查看原始JSON字符串

从那里很容易用JsonConverter属性标记属性

public class Skills
    {
        [JsonConverter(typeof(MyConverter))]
        public List<Skill> Skill { get; set; }
    }
公共课技能
{
[JsonConverter(类型(MyConverter))]
公共列表技能{get;set;}
}
并写入转换器:

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);
        }
    }
公共类MyConverter:JsonConverter
{
公共重写对象ReadJson(JsonReader阅读器,类型objectType,对象existingValue,JsonSerializer序列化程序)
{
if(reader.TokenType==JsonToken.StartArray)
{
返回序列化程序。反序列化(读取器);
}
其他的
{
Skill=序列化程序。反序列化(读取器);
返回新列表(新[]{skill});
}
}      
公共重写void WriteJson(JsonWriter编写器、对象值、JsonSerializer序列化器)
{
writer.WriteValue(值);
}
}

希望它能帮助到某人。

我想,使用您当前的JSON,您描述的是
Skill
包含一个集合,而不是
Skills
。请尝试使用以下JSON:

        "Skills": [
            {
                "@Id": "1",
                "@Name": "Developer"
            },
            {
                "@Id": "2",
                "@Name": "Tester"
            }
        ]
同样的情况也适用于定义
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; }
        }
    }
[TestFixture]
公共类JSONTester
{
[测试]
public void Json_反序列化()
{
var json=@”{
“”xml“”:{
“@version”:“1.0”,
“@encoding”:“utf-8”
},
“人”:{
“人”:[{
“@Id”:“1”,
“@Name”:“John”,
“@姓氏”:“史密斯”
},
{
“@Id”:“2”,
“@Name”:“John”,
“姓氏”:“史密斯”,
“技能”:{
“技能”:[{
“@Id”:“1”,
“@Name”:“开发人员”
},
{
“@Id”:“2”,
“@Name”:“测试员”
}]
}
}]
}
}";
var persons=JsonConvert.DeserializeObject(json);
Assert.AreEqual(persons.persons.Person[1].Skills.Skill.Count,2);
}
公共类根对象
{
公共Xml{get;set;}
公众人物{get;set;}
}
公共类Xml
{
公共字符串版本{get;set;}
公共字符串编码{get;set;}
}
公共阶层人士
{
公共列表人员{get;set;}
}
公开课技能
{
公共int Id{get;set;}
公共字符串名称{get;set;}
}
公共课技能
{
公共列表技能{get;set;}
}
公共阶层人士
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共字符串姓氏{get;set;}
公共技能{get;set;}
}
}

我无法更改JSON,如果可以的话,我会按照您的建议进行更改。但这仍然是一个有效的JSON。我对你的答案投了赞成票,因为它把我推向了正确的方向。全部答案都在我的更新中。从文件中读取json,并用代码反序列化,这一切对我来说都很好。我用答案更新了我的问题。答案很棒。你应该把它标记为已接受的答案。这对我来说太完美了。我所做的唯一改变是使转换器通用,而不是针对任何一种类型(在您的示例中是技能)进行硬编码@GregLoehr很高兴它有所帮助。我还实现了一个通用转换器。这只是给定问题的一个例子。如果你回答自己的问题,答案应该是下面的实际答案
        "Skills": [
            {
                "@Id": "1",
                "@Name": "Developer"
            },
            {
                "@Id": "2",
                "@Name": "Tester"
            }
        ]
    [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; }
        }
    }