如何使用[DefaultValue]属性在JSON序列化时忽略值为true的布尔属性
基于[DefaultValue]特性的通用JSON序列化忽略方案
针对你提出的需求——序列化时忽略标记了[DefaultValue(true)]且值为true的布尔属性,可以通过**自定义类型信息解析器(JsonTypeInfoResolver)**实现通用解决方案,无需针对每个属性单独处理。
实现思路
System.Text.Json默认的IgnoreDefaultValues选项仅识别.NET类型的原生默认值(比如bool的默认值是false),无法识别[DefaultValue]特性指定的自定义默认值。我们可以通过自定义JsonTypeInfoResolver,遍历属性并检查[DefaultValue]特性,为符合条件的属性设置序列化判断逻辑:仅当属性值不等于特性指定的默认值时,才将其序列化。
完整代码示例
1. 自定义DefaultValueContractResolver
using System.ComponentModel; using System.Text.Json; using System.Text.Json.Serialization; public class DefaultValueContractResolver : DefaultJsonTypeInfoResolver { public override JsonTypeInfo GetTypeInfo(Type type, JsonSerializerOptions options) { JsonTypeInfo typeInfo = base.GetTypeInfo(type, options); foreach (JsonPropertyInfo property in typeInfo.Properties) { // 获取属性上的DefaultValueAttribute var defaultValueAttr = property.AttributeProvider.GetCustomAttributes(typeof(DefaultValueAttribute), inherit: false) .Cast<DefaultValueAttribute>() .FirstOrDefault(); if (defaultValueAttr != null && property.PropertyType == typeof(bool)) { // 仅处理默认值为true的布尔属性 if (defaultValueAttr.Value is true) { // 设置序列化条件:仅当属性值不等于默认值(true)时才序列化 property.ShouldSerialize = (obj, value) => !(bool)value; } } } return typeInfo; } }
2. 配置序列化选项并测试
// 配置序列化选项,使用自定义解析器 var options = new JsonSerializerOptions { TypeInfoResolver = new DefaultValueContractResolver(), WriteIndented = true // 格式化输出,方便查看 }; // 创建默认实例(BoolProperty3和BoolProperty4的值为true) var myRecord = new MyRecord(); string json = JsonSerializer.Serialize(myRecord, options); Console.WriteLine(json); // 输出:{} // 修改BoolProperty3为false var modifiedRecord = new MyRecord { BoolProperty3 = false }; json = JsonSerializer.Serialize(modifiedRecord, options); Console.WriteLine(json); // 输出: // { // "BoolProperty3": false // }
代码说明
- 自定义解析器会遍历目标类型的所有属性,检查是否存在
[DefaultValue]特性。 - 对于类型为
bool且特性指定默认值为true的属性,设置ShouldSerialize回调:当属性值为true时跳过序列化,值为false时保留。 - 该方案是通用的,所有标记了
[DefaultValue(true)]的布尔属性都会自动应用此规则,无需重复配置。
内容的提问来源于stack exchange,提问作者Theodor Zoulias
相关产品推荐
相关产品推荐

