How to ignore false values with System.Text.Json

我的梦境 提交于 2020-12-09 03:56:51

问题


I'm migrating from Newtonsoft.Json to System.Text.Json in my .NET Core 3.0 application. I'm trying to ignore false values.

In System.Text.Json I found the option to ignore null values:

JsonSerializerOptions.IgnoreNullValues = true;

But I cannot find the option to ignore false values in System.Text.Json.

Does someone know how can this be achieved with System.Text.Json?

Or if someone know the equivalent of Newtonsoft DefaultValueHandling = DefaultValueHandling.Ignore option that would be fantastic too.


回答1:


This is implemented in .Net 5.0:

Support ignoring value-type defaults

This version introduces JsonIgnoreCondition enum:

/// When specified on JsonSerializerOptions.DefaultIgnoreCondition,
/// determines when properties and fields across the type graph are ignored.
/// When specified on JsonIgnoreAttribute.Condition, controls whether
/// a property is ignored during serialization and deserialization. This option
/// overrides the setting on JsonSerializerOptions.DefaultIgnoreCondition.
public enum JsonIgnoreCondition
{
    /// Property is never ignored during serialization or deserialization.
    Never = 0,
    /// Property is always ignored during serialization and deserialization.
    Always = 1,
    /// If the value is the default, the property is ignored during serialization.
    /// This is applied to both reference and value-type properties and fields.
    WhenWritingDefault = 2,
    /// If the value is <see langword="null"/>, the property is ignored during serialization.
    /// This is applied only to reference-type properties and fields.
    WhenWritingNull = 3,
}

Specifically JsonIgnoreCondition.WhenWritingDefault will suppress false Boolean values. It may be applied in one of two ways. Firstly, you can apply it directly to a member using JsonIgnoreAttribute.Condition:

public class Model
{
    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
    public bool Value { get; set; }
}

Demo fiddle #1 here.

Secondly, you may set it in JsonSerializerOptions.DefaultIgnoreCondition:

Specifies a condition to determine when properties with default values are ignored during serialization or deserialization. The default value is Never.

I.e. given the following model:

public class Model
{
    public bool Value { get; set; }
}

You may serialize it as follows to skip serialization of false values in runtime:

var options = new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault };
var json = JsonSerializer.Serialize(model, options);

Demo fiddle #2 here.

Notes:

  1. The .Net 5.0 docs for JsonIgnoreCondition appear to have some inaccuracies. Firstly, they claim that WhenWritingDefault means that

    Property will only be ignored if it is null.

    However, in fact the property will be ignored if it is default as stated in the source code.

    Secondly, they claim that WhenWritingNull

    is applied only to reference-type properties and fields.

    However, testing shows that it applies to nullable value type members as well. E.g. given the model:

    public class Model
    {
        public bool? Value { get; set; }
    }
    

    Serializing with DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault omits Value when it it is null:

    var model = new Model(); // Leave value null
    
    var options = new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault };
    Console.WriteLine(JsonSerializer.Serialize(model, options)); // Prints {}
    

    Demo fiddle #3 here.

  2. Setting JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault applies to all value types not just bool. Thus if you have any double, int, DateTime, decimal (including a zero-valued decimal with a specified number of digits such as decimal.Parse("0.0000")) or other value type members, they will be omitted when the value equals the default.

    There does not appear to be a way to globally skip serialization of only default bool valued members while still serializing other value-type members, which could be done in Json.NET via a custom contract resolver.

    Demo fiddle #4 here.

  3. In determining whether a member has a default value, the default value for the type of the value (i.e. default(T)) is used. Unlike Json.NET, DefaultValueAttribute is not taken into consideration.

    Demo fiddle #5 here.

  4. Prior to .Net 5.0 you would need to create a custom JsonConverter for the containing type (i.e. Model in the above examples) and manually skip or serialize each member as desired.



来源:https://stackoverflow.com/questions/58225273/how-to-ignore-false-values-with-system-text-json

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!