过滤JSon信息

时间:2014-06-20 18:44:12

标签: c# .net json

我正在接收不同形式的JSON数据(并非所有我将收到的json文件都会有相同的条目)

通常对Parse JSon我使用动态类,如果所有JSON文件具有相同的条目但在这种情况下它不起作用,则该类正在工作。

例如,对于以下数据:

[
    {
        "Player_Name": "Zlatan Ibrahimovic",
        "Country": "Sweeden",
    },
    {
        "Player_Name": "Pavel Nedved",
        "Country": "Czech Republic",
        "Personal_Honours": 
        {
            "Ballon_DOr": "One",
        },
    }
]

前两个元素共享两个第一个条目“Player_Name”和“Country”,但第二个元素有第二个条目,即“Personal_Honours”

所以,如果我这样做:

StreamReader reader = File.OpenText("TextFile1.txt");
List<PlayerData> DataList;
dynamic json = JsonConvert
    .DeserializeObject<dynamic>(reader.ReadToEnd());


DataList = new List<PlayerData>();
foreach (dynamic data in json)
{
    DataList.Add(new PlayerData
    {
        Name = json.Player_Name,
        Country = json.Country , 
        BallonDor = json.Personal_Honours.Ballon_DOr
    });
}

这个班级:

public class PlayerData
{
    public string Name { get; set; }
    public string BallonDor {get; set; }
    public string MarketValue { get; set; }
    public string CurrentClub { get; set; }
}

我得到RuntimeBinderException,因为第一个条目不包含Personal_Honours“如果将要解析的JSON将包含此条目,我将不会事先知道

如何管理此错误?

2 个答案:

答案 0 :(得分:1)

如果您不想为JSON对象使用具体类,可以使用匿名类的强大功能:只需定义使用所有可能属性的示例对象,如下所示:

        var sample = new[]
        {
            new
            {
                Player_Name = "",
                Country = "",
                Personal_Honours = new
                {
                    Ballon_DOr = "",
                },
            }
        };

并使用其.GetType()传递给JSON反序列化器,如下所示:

        dynamic json = JsonConvert.DeserializeObject(myJsonString, sample.GetType());

以下是基于您的来源的完整工作示例:

internal class Program
{
    public class PlayerData
    {
        public string Name { get; set; }
        public string BallonDor { get; set; }
        public string Country { get; set; }
        public string MarketValue { get; set; }
        public string CurrentClub { get; set; }
    }

    private static void Main(string[] args)
    {
        var sample = new[]
        {
            new
            {
                Player_Name = "",
                Country = "",
                Personal_Honours = new
                {
                    Ballon_DOr = "",
                },
            }
        };

        dynamic json = JsonConvert.DeserializeObject(@"[
{
  ""Player_Name"": ""Zlatan Ibrahimovic"",
  ""Country"": ""Sweeden"",
},
{
""Player_Name"": ""Pavel Nedved"",
 ""Country"": ""Czech Republic"",
  ""Personal_Honours"": {
  ""Ballon_DOr"": ""One"",
},
}
]", sample.GetType());

        var dataList = new List<PlayerData>();
        foreach (var data in json)
        {
            dataList.Add(
                new PlayerData
                {
                    Name = data.Player_Name,
                    Country = data.Country,
                    BallonDor = data.Personal_Honours == null ? null : data.Personal_Honours.Ballon_DOr
                });
        }
    }
}

答案 1 :(得分:0)

你正在混合东西。

deserilizer不知道也不在乎,您希望如何保存数据。它只获取deserilize和Object类型的字符串以使用deserilized数据创建实例。

你将第一堂课与第二堂课混为一谈。

例如,我会将其分配如下:

Player class:
- Name (string)
- Country (string)
- PersonalHonours (class)

PersonalHonours class
- BallonDOr (string)
- etc..

当然,如果命名不同,很多部分的命名都是&#39; _&#39;是不同的,你应该&#34;告诉&#34;通过添加到属性[JsonProperty("Ballon_DOr")]属性,实际上与另一个键绑定的deserilizer。

毕竟,你只需要在整个琴弦上使用你的deserilizer,它就会让你准备好使用它。