How to ignore an array item during deserialization of JSON string

巧了我就是萌 提交于 2019-12-12 17:20:34

问题


It seems to be very simple, but I just can't figure out how to do it. I use an external api to get JSON results (using Newtonsoft.JSON), problem is a poor design which leaves me with a array with mixed types like this:

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

This will result in an object like:

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

I want to ignore those date strings and deserialize the objects into a typed array

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

Any idea's how to achieve this kind of behavior?

Update: Maybe I wasn't clear about it, but I'm not looking for a solution which does soms transformation after the deserialization. I want some integrated solution, eg with a JsonConverter.


回答1:


This is possible to do with a custom JsonConverter.

Assuming that you have your classes set up like this:

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

Then you can use this JsonConverter to handle the deserialization of the JSON array. This will ignore all the plain strings (dates) in the array and only try to deserialize the objects.

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

Here is demo program:

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

And here is the output:

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

Is this what you are looking for?




回答2:


When you are serializing an Object that time you can configure which property to ignore, if are willing to do so. If you have done that way then you have to iterate the list List<Object> data to find Team Object and put them in separate list.



来源:https://stackoverflow.com/questions/19700770/how-to-ignore-an-array-item-during-deserialization-of-json-string

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!