如何在C#中解析JSON子集合

3
编辑:以下问题似乎是在“items”数组上放置“bars”标签。我已经尝试使用“JavaScriptSerializer”和“NewtonSoft”工具,但当该集合存在时,会发生错误。 错误:无法将当前JSON对象(例如{\"name\":\"value\"})反序列化为类型'System.Collections.Generic.List...

我从调用RESTful Web服务返回JSON字符串。我已经找出如何将其转换为C#对象。

JSON示例:

{
"property1": "value1",
"property2": "value2"
}

JSON解析的示例类:

public class FooClass
{
public string Property1 { get; set; }
public string Property2 { get; set; }
}

我正在使用 System.Web.Extensions 命名空间中的 "JavaScriptSerializer" 类...效果非常好!
现在,如果 JSON 有一个集合项怎么办? 就像这样:
{
"property1": "value1",
"property2": "value2",
"bars": {
"items": [
{
"sub_property1": "sub_value1",
"sub_property2": "sub_value2"
},
...
]
}
}

我希望能为我的“FooClass”类做类似于以下的事情:

public class FooClass
{
public string Property1 { get; set; }
public string Property2 { get; set; }
public List<BarClass> Bars { get; set; }
}

public class BarClass
{
public string Sub_Property1 { get; set; }
public string Sub_Property2 { get; set; }
}

有没有一种方法可以告诉JavaScriptSerializer类,“items”数组等同于“Bars”,以便它们可以被“解析并进入”类中?
谢谢您能给出的任何建议。

请参考以下链接:https://dev59.com/X3NA5IYBdhLWcg3wEpkU - Jimmy
2个回答

1

没问题——这种行为是自动发生的。重要的是,你的BarClass必须有一个无参构造函数(我认为这对于序列化类通常也是如此)。JavaScriptSerializer反序列化方法接受你的类型以用于重建对象,并遍历你类中的所有子类型。

从MSDN文档中可以看到:"在反序列化期间,序列化程序的当前类型解析器被引用,该解析器确定在转换嵌套在数组和字典类型内部的元素时要使用的托管类型。因此,反序列化过程会迭代输入的所有嵌套元素。"

using System.Collections.Generic; 
using System.Web.Script.Serialization;
namespace ConsoleApplication1
{
    class Program
    {


        private static void Main(string[] args)
        {
            var person = new Person();
            person.Name = "reacher gilt";
            person.Address = "100 East Way";
            person.Age = 74; 
            person.Aliases = new List<string>(new []{"teddy", "freddy", "eddy", "Betty"});
            person.Bars = new List<BarClass>(new[]{ 
                new BarClass("beep","boop"),
                new BarClass("meep","moop"),
                new BarClass("feep","foop"),
            });
            JavaScriptSerializer serializer = new JavaScriptSerializer();

            string jsonString = serializer.Serialize(person);

            var rehydrated = serializer.Deserialize<Person>(jsonString);
        }

    }


    class Person
    {
        public string Name { get; set; }

        public string Address { get; set; }

        public int Age { get; set; }

        public List<string> Aliases;
        public List<BarClass> Bars { get; set; }
    }
    class BarClass
    { 
        public string Sub_Property1 { get; set; }
        public string Sub_Property2 { get; set; }
        public BarClass() { }
        public BarClass (string one, string two)
        {
            Sub_Property1 = one;
            Sub_Property2 = two;
        }
    }
}

编辑:在教练罗布的澄清评论之后:

using System.Collections.Generic;
using System.Web.Script.Serialization;
namespace ConsoleApplication1
{
    class Program
    {


        private static void Main(string[] args)
        {
            var person = new Person();
            person.Name = "reacher gilt";
            person.Address = "100 East Way";
            person.Age = 74; 
            person.Aliases = new List<string>(new []{"teddy", "freddy", "eddy", "Betty"});
            person.Bars = new Dictionary<string, List<BarClass>>();

            person.Bars.Add("items",
                new List<BarClass>(new[]{ 
                new BarClass("beep","boop"),
                new BarClass("meep","moop"),
                new BarClass("feep","foop"),
            }));
            JavaScriptSerializer serializer = new JavaScriptSerializer();

            string jsonString = serializer.Serialize(person);

            var rehydrated = serializer.Deserialize<Person>(jsonString);
        }

    }


    class BarClass
    { 
        public string Sub_Property1 { get; set; }
        public string Sub_Property2 { get; set; }
        public BarClass() { }
        public BarClass (string one, string two)
        {
            Sub_Property1 = one;
            Sub_Property2 = two;
        }
    }

    class Person
    {
        public string Name { get; set; }

        public string Address { get; set; }

        public int Age { get; set; }

        public List<string> Aliases;
        public Dictionary <string, List<BarClass> >Bars { get; set; }
    }
}

这将会得到类似于JSON的数据:

{
    "Aliases":
    [
        "teddy",
        "freddy",
        "eddy",
        "Betty"
    ],
    "Name":"reacher gilt",
    "Address":"100 East Way",
    "Age":74,
    "Bars":
    {
        "items":
        [
            {
                "Sub_Property1":"beep",
                "Sub_Property2":"boop"
            },

            {
                "Sub_Property1":"meep",
                "Sub_Property2":"moop"
            },

            {
                "Sub_Property1":"feep",
                "Sub_Property2":"foop"
            }
        ]
    }
}

我也看到有人使用DataContractJsonSerializer来序列化为json,但是问题中指定了System.Web.Script.Serialization.JavaScriptSerializer。


请查看上面的编辑。由于“items”数组嵌套在“bars”属性下面,因此这种方法不起作用。有什么想法吗? - coach_rob
嗯,看这里:JSON和你的类之间有一个区别。JSON在Bars和实际列表之间有一个额外的数据结构。我已经编辑了答案以使类与JSON匹配,但你必须决定这是否是适合你的“正确”数据结构。 - Reacher Gilt
通过将代码从:public List<BarClass> Bars { get; set; } 改为 public Dictionary<string, List<BarClass>> Bars { get; set;},问题得以解决。虽然数据结构不是最理想的,但比我找到的其他方法更易于管理(例如维护自定义JSON解析)。非常感谢您的帮助! - coach_rob

0

试试这个:

[DataContract]
public class FooClass
{
    [DataMember]
    public string Property1 { get; set; }

    [DataMember]
    public string Property2 { get; set; }

    [DataMember]
    public Bars Bars { get; set; }
}

[DataContract]
public class Bars
{
    [DataMember]
    public List<Item> Items { get; set; }
}

[DataContract]
public class Item
{
    [DataMember]
    public string Sub_Property1 { get; set; }

    [DataMember]
    public string Sub_Property2 { get; set; }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接