Matt Burland
Matt Burland

Reputation: 45155

Ignore property when serializing under certain conditions

Json.net has a very useful property that can be set on the JsonPropertyAttribute called NullValueHandling. If you decorate a property like this:

[JsonProperty(NullValueHandling=NullValueHandling.Ignore)]
string MyProp { get; set; }

Then if MyProp is null, it won't be included in the output at all.

I would like to do something similar, but with a different condition for exclusion. For example - say we have an enum

public enum MyEnum { None = 0, Value1 = 1, Value2 = 2, Value3 = 4 };

And a property

MyEnum MyProp { get; set; }

Then I'd like to have MyProp completely excluded from the input if MyProp == MyEnum.None.

I know one solution would be to use MyEnum? instead of MyEnum and then I could use NullValueHandling again, but I can't use nullable here. I thought I might be able to use a JsonConverter so I tried to subclass StringEnumConverter (because I want them outputted as strings ideally):

    public class MyEnumConverter : Newtonsoft.Json.Converters.StringEnumConverter
    {            
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(MyEnum);
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            // don't write if value is none
            var v = (MyEnum)value;
            if (v == MyEnum.None)
            {
                // what to do here? The two options below both include the property as null
                //writer.WriteNull();
                //serializer.Serialize(writer, null);
                return;        // just returning without doing anything will break the serialization
            }
            base.WriteJson(writer, value, serializer);
        }
    }

Can I, or should I, try subclassing JsonProperty? And if so, what would I need to override to get the behavior I want?

I hoping to avoid having to attach a converter to the class that contains this property because then I have to manually serialize the whole thing, which is a pain.

Upvotes: 5

Views: 3123

Answers (1)

L.B
L.B

Reputation: 116178

You can use a method with the signature public bool ShouldSerialize*PropertyName*().

public enum MyEnum { None = 0, Value1 = 1, Value2 = 2, Value3 = 4 };

public class SomeClass
{
    public MyEnum MyProp { get; set; }
    public string Test = "aaaa";

    public bool ShouldSerializeMyProp()
    {
        return MyProp != MyEnum.None;
    }
}

var retVal1 = JsonConvert.SerializeObject(new SomeClass() { MyProp= MyEnum.None });
var retVal2 = JsonConvert.SerializeObject(new SomeClass() { MyProp = MyEnum.Value1 });

OUTPUT:

retVal1: {"Test":"aaaa"}

retVal2: {"Test":"aaaa","MyProp":1}

Upvotes: 10

Related Questions