如何使用 System.Text.Json 忽略错误值
Posted
技术标签:
【中文标题】如何使用 System.Text.Json 忽略错误值【英文标题】:How to ignore false values with System.Text.Json 【发布时间】:2020-02-02 03:15:00 【问题描述】:我正在我的 .NET Core 3.0 应用程序中从 Newtonsoft.Json
迁移到 System.Text.Json
。我试图忽略错误值。
在System.Text.Json
我找到了忽略空值的选项:
JsonSerializerOptions.IgnoreNullValues = true;
但我在System.Text.Json
中找不到忽略错误值的选项。
有人知道如何使用System.Text.Json
实现这一点吗?
或者,如果有人知道相当于 Newtonsoft DefaultValueHandling = DefaultValueHandling.Ignore
的选项,那也太棒了。
【问题讨论】:
如果我理解你的正确,我认为你必须使用属性 [Default(false)]。 感谢@AndreasSchmidt 属性[DefaultValue(false)]
来自Newtonsoft.Json
。我想使用System.Text.Json
我很确定它不是来自 Newtonsoft.Json:docs.microsoft.com/en-us/dotnet/api/…
抱歉你是对的@AndreasSchmidt!它实际上来自 System.ComponentModel
命名空间。不幸的是[DefaultValue(false)]
不起作用。
@dbc 不幸的是,这不是真的。你只负责写值,属性名已经写好了。所以如果你不写,你会得到一个无效的 JSON
【参考方案1】:
这是在.Net 5.0中实现的:
支持忽略值类型默认值
此版本引入JsonIgnoreCondition
枚举:
/// 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,
特别是 JsonIgnoreCondition.WhenWritingDefault
将抑制 false
布尔值。它可以以两种方式之一应用。首先,您可以使用JsonIgnoreAttribute.Condition
直接将其应用于成员:
public class Model
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
public bool Value get; set;
演示小提琴 #1 here.
其次,你可以设置在JsonSerializerOptions.DefaultIgnoreCondition
:
指定一个条件来确定在序列化或反序列化期间何时忽略具有默认值的属性。默认值为Never。
即给定以下模型:
public class Model
public bool Value get; set;
您可以按如下方式对其进行序列化,以在运行时跳过false
值的序列化:
var options = new JsonSerializerOptions DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault ;
var json = JsonSerializer.Serialize(model, options);
演示小提琴#2 here.
注意事项:
.Net 5.0 docs for JsonIgnoreCondition
似乎有一些不准确之处。首先,他们声称WhenWritingDefault
意味着
只有
null
的属性才会被忽略。
然而,事实上,如果它是source code 中所述的default
,则该属性将被忽略。
其次,他们声称WhenWritingNull
仅适用于引用类型的属性和字段。
但是,测试表明它也适用于nullable 值类型成员。例如。给定模型:
public class Model
public bool? Value get; set;
使用DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
进行序列化时,Value
为 null:
var model = new Model(); // Leave value null
var options = new JsonSerializerOptions DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault ;
Console.WriteLine(JsonSerializer.Serialize(model, options)); // Prints
演示小提琴#3 here.
设置JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
适用于所有值类型,而不仅仅是bool
。因此,如果您有任何double
、int
、DateTime
、decimal
(包括具有指定位数的零值小数,例如decimal.Parse("0.0000")
)或其他值类型成员,它们将被省略该值等于默认值。
似乎没有一种方法可以全局跳过仅默认 bool
值成员的序列化,同时仍序列化其他值类型成员,这可以通过自定义合约解析器在 Json.NET 中完成。
演示小提琴 #4 here.
在确定成员是否具有默认值时,使用值的类型的默认值(即default(T)
)。与Json.NET 不同,DefaultValueAttribute
不被考虑在内。
演示小提琴 #5 here.
在 .Net 5.0 之前,您需要为包含类型创建一个 custom JsonConverter
(即上述示例中的 Model
)并根据需要手动跳过或序列化每个成员。
【讨论】:
以上是关于如何使用 System.Text.Json 忽略错误值的主要内容,如果未能解决你的问题,请参考以下文章
.NET 6 中 System.Text.Json 的新特性
如何在反序列化之前使用 System.Text.Json 验证 JSON
如何在 System.Text.Json 中使用 JsonConstructor 属性
如何将类字段与 System.Text.Json.JsonSerializer 一起使用?
如何使用 JsonConverter 在 System.Text.Json.JsonSerializer.Serialize() 中排除属性被序列化