Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 726
Matt Burland Avatar asked Aug 13 '14 18:08

Matt Burland


People also ask

How can you prevent a property from being serialized?

You can prevent member variables from being serialized by marking them with the NonSerialized attribute as follows. If possible, make an object that could contain security-sensitive data nonserializable. If the object must be serialized, apply the NonSerialized attribute to specific fields that store sensitive data.

How do I ignore JSON property based on condition?

To ignore individual properties, use the [JsonIgnore] attribute. You can specify conditional exclusion by setting the [JsonIgnore] attribute's Condition property. The JsonIgnoreCondition enum provides the following options: Always - The property is always ignored.

How do I ignore JSON property while Deserialization?

If there are fields in Java objects that do not wish to be serialized, we can use the @JsonIgnore annotation in the Jackson library. The @JsonIgnore can be used at the field level, for ignoring fields during the serialization and deserialization.

Which of the following attribute should be used to indicate the property must not be serialized while using .JSON serializer?

Apply a [JsonIgnore] attribute to the property that you do not want to be serialized.


1 Answers

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}

like image 76
L.B Avatar answered Sep 22 '22 01:09

L.B