问题
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:
The .Net 5.0 docs for JsonIgnoreCondition appear to have some inaccuracies. Firstly, they claim that
WhenWritingDefault
means thatProperty 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
omitsValue
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.
Setting
JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
applies to all value types not justbool
. Thus if you have anydouble
,int
,DateTime
,decimal
(including a zero-valued decimal with a specified number of digits such asdecimal.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.
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.
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