Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

equivalent of default value during Converting my newtonsoft implementation to new JSON library in .net core 3.0

I am converting my .net core 2.1 to 3.0 with upgrade from newtonsoft to builtin JSON serializer.

I have some code for setting default value

[DefaultValue(true)]
[JsonProperty("send_service_notification", DefaultValueHandling = DefaultValueHandling.Populate)]
public bool SendServiceNotification { get; set; }

Please help me out with equivalent in System.Text.Json.Serialization.

like image 571
Kamran Shahid Avatar asked Oct 23 '19 07:10

Kamran Shahid


1 Answers

As noted in Issue #38878: System.Text.Json option to ignore default values in serialization & deserialization, as of .Net Core 3 there is no equivalent to the DefaultValueHandling functionality in System.Text.Json.

.NET 5 and later introduce JsonIgnoreAttribute.Condition, which has the following values:

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,
}

While JsonIgnoreCondition superficially resembles DefaultValueHandling, System.Text.Json ignores custom default values applied via DefaultValueAttribute. Instead the default value used is always default(T). E.g. the following combination of attributes:

[DefaultValue(true)]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
[JsonPropertyName("send_service_notification")]
public bool SendServiceNotification { get; set; }

Will result in SendServiceNotification being skipped when false not true. In addition, System.Text.Json will not automatically populate the default value onto your model if not present in the JSON.

That being said, you are using DefaultValueHandling.Populate:

Members with a default value but no JSON will be set to their default value when deserializing.

This can be achieved by setting the default value in the constructor or property initializer:

//[DefaultValue(true)] not needed by System.Text.Json
[System.Text.Json.Serialization.JsonPropertyName("send_service_notification")]
public bool SendServiceNotification { get; set; } = true;

In fact the documentation for DefaultValueAttribute recommends doing exactly that:

A DefaultValueAttribute will not cause a member to be automatically initialized with the attribute's value. You must set the initial value in your code.

Demo fiddle here.

like image 142
dbc Avatar answered Sep 30 '22 12:09

dbc