如何用Newtonsoft实现JsonProperty序列化与反序列化不同值?
问题描述
从服务器拿到的源JSON是这样的:
{ "Property A": .098 }
我用下面的C#类做反序列化,能正常转成对象:
public class Foo { [JsonProperty("Property A")] public decimal PropertyA { get; set; } } var ret = JsonConvert.DeserializeObject<Foo>(File.ReadAllText(someJsonFilePath));
但现在要把这个对象序列化回JSON时,希望输出格式变成:
{ "property_a": .098 }
目前我是靠创建另一个只改了JsonProperty字段名的重复类来实现的,想问能不能用Newtonsoft实现反序列化用指定名称、序列化用另一个名称,不用搞重复类?
解决方案
当然可以,不用创建重复类,给你两种常用方法:
方法一:自定义ContractResolver(通用型,适合多属性场景)
写一个自定义的契约解析器,区分序列化和反序列化场景,给目标属性指定不同的名称:
public class CustomContractResolver : DefaultContractResolver { private readonly bool _isSerialization; public CustomContractResolver(bool isSerialization) { _isSerialization = isSerialization; } protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) { JsonProperty property = base.CreateProperty(member, memberSerialization); // 对PropertyA属性做名称映射 if (member.Name == nameof(Foo.PropertyA)) { property.PropertyName = _isSerialization ? "property_a" : "Property A"; } return property; } }
使用的时候分别指定不同的解析器:
// 反序列化用反序列化专用配置 var deserializeSettings = new JsonSerializerSettings { ContractResolver = new CustomContractResolver(isSerialization: false) }; var foo = JsonConvert.DeserializeObject<Foo>(jsonString, deserializeSettings); // 序列化用序列化专用配置 var serializeSettings = new JsonSerializerSettings { ContractResolver = new CustomContractResolver(isSerialization: true), Formatting = Formatting.Indented }; var outputJson = JsonConvert.SerializeObject(foo, serializeSettings);
方法二:匿名对象序列化(轻量型,适合少属性场景)
如果只有少数几个属性需要改名称,直接在序列化时构造匿名对象就行,代码更短:
var outputJson = JsonConvert.SerializeObject(new { property_a = foo.PropertyA }, Formatting.Indented);
内容的提问来源于stack exchange,提问作者Josh
相关产品推荐
相关产品推荐

