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

任何想法如何实现这种行为?

更新:也许我不清楚,但我不是在寻找在反序列化后进行 soms 转换的解决方案。我想要一些集成的解决方案,例如使用 JsonConverter。

4

2 回答 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

这是你想要的?

于 2013-10-31T22:09:40.630 回答
0

当您序列化一个对象时,您可以配置要忽略的属性,如果愿意的话。如果你这样做了,那么你必须迭代列表List<Object> data以找到TeamObject 并将它们放在单独的列表中。

于 2013-10-31T08:47:34.243 回答