在某些条件下序列化时忽略属性

Mat*_*and 4 c# serialization json.net

Json.net有一个非常有用的属性,可以在被JsonPropertyAttribute调用的上设置NullValueHandling.如果您装饰这样的属性:

[JsonProperty(NullValueHandling=NullValueHandling.Ignore)]
string MyProp { get; set; }
Run Code Online (Sandbox Code Playgroud)

然后,如果MyProp为null,则根本不会包含在输出中.

我想做类似的事情,但有不同的排除条件.例如 - 说我们有一个枚举

public enum MyEnum { None = 0, Value1 = 1, Value2 = 2, Value3 = 4 };
Run Code Online (Sandbox Code Playgroud)

和一个财产

MyEnum MyProp { get; set; }
Run Code Online (Sandbox Code Playgroud)

然后我想MyProp完全排除输入if MyProp == MyEnum.None.

我知道一个解决方案是使用MyEnum?而不是MyEnum然后我可以NullValueHandling再次使用,但我不能在这里使用nullable.我以为我可以使用一个,JsonConverter所以我尝试了子类StringEnumConverter(因为我希望它们理想地输出为字符串):

    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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

我可以或者应该尝试继承子类JsonProperty吗?如果是这样,我需要覆盖什么来获得我想要的行为?

我希望避免必须将转换器附加到包含此属性的类,因为然后我必须手动序列化整个事情,这是一个痛苦.

L.B*_*L.B 9

您可以使用带签名的方法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;
    }
}
Run Code Online (Sandbox Code Playgroud)
var retVal1 = JsonConvert.SerializeObject(new SomeClass() { MyProp= MyEnum.None });
var retVal2 = JsonConvert.SerializeObject(new SomeClass() { MyProp = MyEnum.Value1 });
Run Code Online (Sandbox Code Playgroud)

OUTPUT:

retVal1: {"Test":"aaaa"}

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