反序列化JSON不JSON.NET工作 [英] Deserialize JSON not working with JSON.NET

查看:315
本文介绍了反序列化JSON不JSON.NET工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用JSON.NET反序列化时,我有以下JSON的一个问题。

I have a problem with the following JSON when deserializing using JSON.NET.

{
    "?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; }
}

当我尝试反序列化

RootObject persons = JsonConvert.DeserializeObject<RootObject>(json);



我得到了以下错误:

i got the following error:

无法反序列化当前的JSON对象(如{名:值})
到类型为
'System.Collections.Generic.List`1 [Project.Models。 Persons.Skill]'
,因为该类型需要一个JSON数组(如[1,2,3]),以正确的反序列化
。要解决这个错误要么改变的JSON到一个JSON数组
(例如:[1,2,3])或改变反序列化的类型,以便它是一个正常的
.NET类型(例如,不是原始类型喜欢整数,而不是一个集合
型一样,可以从一个JSON
对象进行反序列化数组或列表)。 JsonObjectAttribute也可以加入,迫使它
从JSON对象反序列化的类型。

Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[Project.Models.Persons.Skill]' 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) 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.

我想这个问题是在符号:

I suppose the problem is in the notation:

"Skills": {
            "Skill": [{

我在想什么,有一个简单的解决这个问题?

What am I missing, is there an easy solution to this problem?

更新:

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

So finally the problem was that it was sometimes a JSON array

"Skills": {
                "Skill": [{

有时一个JSON对象

"Skills": {
                "Skill": {

但粘贴时/检查我的代码放到它总是被格式化为一个JSON数组验证,所以我已经检查它使用监视窗口看到原始的JSON字符串。

But when pasting/checking my code into validators it would always be formatted as a JSON array so i've inspected it using watch window to see the raw json string.

从那里很容易标记一个JsonConverter属性的属性。

From there it was easy to mark the property with a JsonConverter attribute

public class Skills
    {
        [JsonConverter(typeof(MyConverter))]
        public List<Skill> Skill { 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);
        }
    }



希望它可以帮助别人。

Hope it helps somebody.

推荐答案

我认为,与当前的JSON,你所描述的技能包含集合,而不是技能。试试这个JSON来代替:

I think, with your current JSON, you are describing that Skill contains a collection, not Skills. Try this JSON instead:

        "Skills": [
            {
                "@Id": "1",
                "@Name": "Developer"
            },
            {
                "@Id": "2",
                "@Name": "Tester"
            }
        ]

同样的道理也适用于你是如何定义的< 。code>人集

The same thing applies to how you are defining the Persons collection.

编辑:

本测试通过对我来说:

    [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; }
        }
    }

这篇关于反序列化JSON不JSON.NET工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆