过滤JSON信息信息、JSON

2023-09-07 08:49:56 作者:撩妹浪子

我接受了不同形式的JSON数据(不是所有的,我会接受将具有相同的条目JSON文件)

I am receiving JSON Data of different forms (Not all of the json files that I will receive will have the same entries)

一般来解析JSON我使用其工作,如果所有的JSON文件具有相同条目的动态类,但它不工作在这种情况下。

Usually to Parse JSon I use the dynamic class which is working if all the JSON files have the same entries but it is not working in this case.

例如以下数据:

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

前两个要素共享两个第一项Player_Name和国家,但第二个元素是Personal_Honours

The first two elements share the two first entries "Player_Name" and "Country" but the second element has a second entry which is "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将包含此项

I get a RuntimeBinderException since the first entry does not Contain Personal_Honours" I will not know in advance if the JSON that will parse will contain this entry

我如何管理这个错误?

推荐答案

如果你不想使用的具体类的JSON对象,你可以使用匿名类的力量:只要定义它使用所有可能的属性样本对象,像这样的:

If you don't want to use concrete classes for JSON objects, you can use the power of anonymous classes: just define the sample object which use all possible properties, like this:

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

和使用其 .GetType()传递给JSON解串器是这样的:

and use its .GetType() to pass to JSON deserializer like this:

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

下面是根据你的源代码完全工作示例:

Here is full working sample based on your sources:

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