C#如何选择JSON序列化属性,剔除未使用的默认值属性?
解决方案
针对你遇到的问题,这里有几种简便的方法可以剔除未修改的默认值属性,无需手动动态添加/移除[JsonIgnore]:
方法1:结合DefaultValueAttribute与DefaultValueHandling.Ignore
先给类的属性标记初始值作为默认值,序列化时配置忽略等于默认值的属性:
using System.ComponentModel; using Newtonsoft.Json; public class Foo { private const string DefaultText = "Hello world! This is a good string!"; [DefaultValue(DefaultText)] public string A { get; set; } = DefaultText; [DefaultValue(DefaultText)] public string B { get; set; } = DefaultText; [DefaultValue(DefaultText)] public string C { get; set; } = DefaultText; }
序列化时添加配置:
var serializeSettings = new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore }; var foo1 = new Foo { A = "Test" }; File.WriteAllText(@"C:\some\path\file1.json", JsonConvert.SerializeObject(foo1, serializeSettings));
生成的file1.json只会包含修改过的A属性,未修改的B、C会被自动忽略。
方法2:用匿名类精准指定序列化属性
如果明确知道每次要序列化的属性,直接用匿名类包装需要的字段,省去特性标记的麻烦:
var foo1 = new Foo { A = "Test" }; // 只序列化修改后的A属性 var serializedContent = JsonConvert.SerializeObject(new { foo1.A }); File.WriteAllText(@"C:\some\path\file1.json", serializedContent);
这种方式代码简洁,完全按需选择序列化内容,适合场景明确的情况。
方法3:自定义ContractResolver自动过滤未修改属性
如果类属性较多,需要自动判断哪些属性被修改,可自定义解析器对比属性当前值和类默认初始值:
using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using System.Reflection; public class IgnoreUnmodifiedResolver : DefaultContractResolver { private readonly object _defaultInstance; public IgnoreUnmodifiedResolver(Type targetType) { _defaultInstance = Activator.CreateInstance(targetType); } protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) { JsonProperty property = base.CreateProperty(member, memberSerialization); var propInfo = (PropertyInfo)member; property.ShouldSerialize = instance => { var currentValue = propInfo.GetValue(instance); var defaultValue = propInfo.GetValue(_defaultInstance); return !Equals(currentValue, defaultValue); }; return property; } }
使用方式:
var serializeSettings = new JsonSerializerSettings { ContractResolver = new IgnoreUnmodifiedResolver(typeof(Foo)) }; var foo2 = new Foo { B = "Test" }; File.WriteAllText(@"C:\some\path\file2.json", JsonConvert.SerializeObject(foo2, serializeSettings));
该解析器会自动对比每个属性的当前值与类默认实例的属性值,只序列化有修改的字段,无需手动配置。
内容的提问来源于stack exchange,提问作者RelativeLayouter
相关产品推荐
相关产品推荐

