Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Newtonsoft JsonConvert.DeserializeObject how to ignore empty objects

Tags:

c#

json.net

I have the following class definitions:

public class Tag
{
    public Guid? TagId { get; set; }
    public string TagText { get; set; }
    public DateTime CreatedOn { get; set; }
}

public class Wiki
{
    public Guid? WikiId { get; set; }
    public string WikiText { get; set; }
    public string Title { get; set; }
    public DateTime CreatedOn { get; set; }
    public IEnumerable<Tag> Tags { get; set; }
}

From the database i get the following json Object:

{
    "WikiId": "83981284-0AD3-4420-90AB-15E3BF6BD7B7",
    "WikiText": "Text",
    "Title": "Title",
    "CreatedOn": "2017-08-07T09:16:06.0800000",
    "Tags": [{}] // <-- here i would like to ignore the empty Tag object
}

When i do now a JsonConvert.DeserializeObject<Wiki>(json) i get a Wiki object with a list of 1 Tag with the values TagId: null, TagText: null and CreatedOn: "0001-01-01T00:00:00"

Is there a way to ignore the empty Tag object while deserializing? I have tried several JsonSerializerSettings but nothing helped.

like image 797
VSDekar Avatar asked Aug 08 '17 15:08

VSDekar


2 Answers

You could use a custom JsonConverter to ignore the empty objects during deserialization. Something like this could work:

class IgnoreEmptyItemsConverter<T> : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType.IsAssignableFrom(typeof(List<T>));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        List<T> list = new List<T>();
        JArray array = JArray.Load(reader);
        foreach (JObject obj in array.Children<JObject>())
        {
            if (obj.HasValues)
            {
                list.Add(obj.ToObject<T>(serializer));
            }
        }
        return list;
    }

    public override bool CanWrite
    {
        get { return false; }
    }

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

To use the converter, just add a [JsonConverter] attribute to your Tags property like this:

public class Wiki
{
    ...
    [JsonConverter(typeof(IgnoreEmptyItemsConverter<Tag>))]
    public IEnumerable<Tag> Tags { get; set; }
}

Fiddle: https://dotnetfiddle.net/hrAFsh

like image 120
Brian Rogers Avatar answered Sep 28 '22 16:09

Brian Rogers


You'll have to detect the empty tag objects post-conversion and remove them yourself. From the deserializer's perspective, {} is a perfectly valid and complete Tag object whose properties are all unset.

Something like the following should work (presuming C# 6):

Wiki wiki = JsonConvert.DeserializeObject<Wiki>(json);
wiki.Tags = Wiki.Tags?.Where(x => x.TagId.HasValue)?.ToList();
like image 23
Jonathan Myers Avatar answered Sep 28 '22 14:09

Jonathan Myers