NET转换器不应序列化属性

NET转换器不应序列化属性

本文介绍了自定义Json.NET转换器不应序列化属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了一个Json.NET转换器,该转换器将所有设置的标志输出为数组.

I have written a Json.NET converter which outputs all the set flags as an array.

enum SampleEnum
{
    None = 0,
    ValueA = 2,
    ValueB = 4
}

SampleEnum flags = SampleEnum.ValueA | SampleEnum.ValueB;
// JSON: ["ValueA", "ValueB"]

现在,如果flagsSampleEnum.None,则该属性不应序列化.因此,我只是不向JsonWriter写任何东西.这是转换器的WriteJson方法的代码.

Now in case flags is SampleEnum.None, the property should not be serialized. Therefore I just don't write anything to the JsonWriter. Here is the code of the WriteJson method of the converter.

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
    if (value is SampleEnum enumValue)
    {
        IEnumerable<SampleEnum> setFlags = GetSetFlags<SampleEnum>(enumValue);

        IEnumerable<string> flagNames = setFlags
            .Where(flag => flag != SampleEnum.None) // Filter out 'None'
            .Select(flag => flag.ToString());

        if (flagNames.Any())
        {
            JArray jArray = JArray.FromObject(flagNames, serializer);
            jArray.WriteTo(writer);
        }
        // Else omit this property
    }
}

但是,如果我在类中具有SampleEnum类型的属性,并且其值为SampleEnum.None,则该属性将被序列化,并且JSON值为null.

However, if I have a property of type SampleEnum in my class and its value is SampleEnum.None, the property is serialized and the JSON value is null.

class SerializedClass
{
    [JsonConverter(typeof(ArrayEnumConverter))]
    public SampleEnum EnumValue { get; set; }
}

SerializedClass obj = new SerializedClass
{
    EnumValue = SampleEnum.None
};
string json = JsonConvert.SerializeObject(obj, new JsonSerializerSettings
{
    NullValueHandling = NullValueHandling.Ignore
});

输出如下:

{
  "EnumValue": null
}

我希望看到的输出:

{}

我该怎么做,以使该属性被忽略而不是为空?

PS:我已经了解了条件属性序列化,但是ShouldSerialize方法不适用于我的情况,我还没有弄清楚如何为我的情况使用IContractResolver.

P.S.: I've read about Conditional Property Serialization, but the ShouldSerialize methods are not suitable in my case and I haven't figured out yet how to use IContractResolver for my case.

推荐答案

A 自定义JsonConverter 不能阻止其值被序列化,因为引用该属性的属性名称在调用转换器时已经被写出.在Json.NET的体系结构中,包含类型的责任是确定要序列化其属性的哪一个.然后,值转换器决定如何对要写入的值进行序列化.

A custom JsonConverter cannot prevent its value from being serialized, because the property name referring to it will already have been written out by the time the converter is invoked. In Json.NET's architecture it is the responsibility of the containing type to decide which of its properties to serialize; the value converter then decides how to serialize the value being written.

作为替代,设置 DefaultValueHandling.Ignore 可以是用于跳过enum成员的序列化,即使应用了转换器也是如此.由于SampleEnum.None的值为0,因此它是标志枚举的默认值.启用此设置(无论是否应用转换器)时,具有此值的成员将被跳过.

As an alternative, the setting DefaultValueHandling.Ignore can be used to skip serialization of enum members even when a converter is applied. Since SampleEnum.None has the value 0, it is the default value for your flags enumeration. Members with this value will this be skipped when the setting is enabled whether or not a converter is applied.

您可以通过 JsonPropertyAttribute.DefaultValueHandling 来启用它. a>:

You can enable DefaultValueHandling by applying it via JsonPropertyAttribute.DefaultValueHandling:

public class SerializedClass
{
    [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
    [JsonConverter(typeof(ArrayEnumConverter))]
    public SampleEnum SampleEnum { get; set; }
}

样本小提琴此处.

偶然地,您应该考虑使用 [Flags] 属性:

Incidentally, you should consider marking your SampleEnum with the [Flags] attribute:

[Flags]
public enum SampleEnum
{
    None = 0,
    ValueA = 2,
    ValueB = 4
}

这是推荐的最佳做法用于标记枚举:

√请应用 System.FlagsAttribute 标记枚举.不要将此属性应用于简单的枚举.

√ DO apply the System.FlagsAttribute to flag enums. Do not apply this attribute to simple enums.

这篇关于自定义Json.NET转换器不应序列化属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-25 13:07