如何在JSON字符串反序列化过程中忽略数组项

3

这似乎很简单,但我就是想不出该怎么做。我使用外部API获取JSON结果(使用Newtonsoft.JSON),问题在于设计不良,导致我得到了一个包含混合类型的数组,如下所示:

{"data":["Monday 13 january", {"id":"1234aa","name":"teamA"},{"id":"1234bb","name":"teamB"}, "Tuesday 14 january", {"id":"1234aa","name":"teamA"}]}

这将会得到一个如下所示的对象:

public class RootObject
{
  public List<object> data { get; set; }
}

我希望忽略那些日期字符串并将对象反序列化为一个类型化数组。
public class RootObject
{
   public List<Team> data { get; set; }
}

有没有想法如何实现这种行为?
更新: 也许我没有表述清楚,但我不是在寻找一个在反序列化后进行某些转换的解决方案。我想要一些集成的解决方案,例如使用JsonConverter。
2个回答

4

您可以通过自定义JsonConverter实现此操作。

假设您已经按照以下方式设置了您的类:

public class RootObject
{
    [JsonProperty("data")]
    [JsonConverter(typeof(TeamListConverter))]
    public List<Team> Teams { get; set; }
}

public class Team
{
    [JsonProperty("id")]
    public string Id { get; set; }
    [JsonProperty("name")]
    public string Name { get; set; }
}

然后你可以使用这个JsonConverter来处理JSON数组的反序列化。这将忽略数组中的所有普通字符串(日期),只尝试反序列化对象。

public class TeamListConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(List<Team>);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JArray array = JArray.Load(reader);
        List<Team> teams = new List<Team>();
        foreach (JToken token in array.Children())
        {
            if (token.Type == JTokenType.Object)
            {
                teams.Add(token.ToObject<Team>());
            }
        }
        return teams;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

这是一个演示程序:

public class Program
{
    public static void Main(string[] args)
    {
        string json = @"
        {
            ""data"":
            [
                ""Monday 13 january"",
                {
                    ""id"":""1234aa"",
                    ""name"":""teamA""
                },
                {
                    ""id"":""1234bb"",
                    ""name"":""teamB""
                }, 
                ""Tuesday 14 january"", 
                {
                    ""id"":""1234aa"",
                    ""name"":""teamA""
                }
            ]
        }";

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

        foreach (Team t in obj.Teams)
        {
            Console.WriteLine(t.Id + " - " + t.Name);
        }
    }
}

以下是输出结果:

1234aa - teamA
1234bb - teamB
1234aa - teamA

这是您正在寻找的内容吗?

这正是我正在寻找的,谢谢!昨晚我也想到了类似的方法,但我使用了两个转换器。你的看起来更好、更干净。今晚我会试一下,如果有效的话就标记一下。谢谢! - Tom Kuijsten

0

当你序列化一个对象时,你可以配置忽略哪些属性,如果你愿意的话。如果你是这样做的,那么你需要遍历列表 List<Object> data 来找到 Team 对象,并将它们放入单独的列表中。


我不明白,我的问题不是关于属性而是如何忽略数组项。请提供一些示例代码,看看您的解决方案是否有用。 - Tom Kuijsten

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