如何为第三方库类动态添加JsonProperty特性实现JSON序列化
解决方案:使用自定义契约解析器(Newtonsoft.Json)
由于第三方类无法直接修改或添加特性,最稳妥的方式是通过Newtonsoft.Json的IContractResolver动态指定属性的JSON序列化名称,完全不需要修改类本身。
步骤1:实现自定义契约解析器
创建继承自DefaultContractResolver的类,重写方法来定义属性名映射规则:
using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using System.Reflection; public class CustomPropertyNameResolver : DefaultContractResolver { // 存储特定类型的属性名映射:键为原属性名,值为序列化用的短名称 private readonly Dictionary<Type, Dictionary<string, string>> _propertyMappings = new() { { typeof(Address), new Dictionary<string, string> { { nameof(Address.Number), "Nmb" }, { nameof(Address.Street), "Str" } } } // 可按需添加其他第三方类的映射规则 }; protected override string ResolvePropertyName(string propertyName) { var currentProperty = (PropertyInfo?)CurrentProperty; if (currentProperty != null && _propertyMappings.TryGetValue(currentProperty.DeclaringType!, out var typeMappings)) { if (typeMappings.TryGetValue(propertyName, out var customName)) { return customName; } } // 无映射规则的属性保留原名称 return base.ResolvePropertyName(propertyName); } }
步骤2:用自定义解析器序列化对象
将自定义解析器传入JsonSerializerSettings,执行序列化:
var person = new Person { Name = "John", Age = 30, PostalAddress = new Address { Number = "123", Street = "Main St", City = "New York", Country = "USA" } }; var settings = new JsonSerializerSettings { ContractResolver = new CustomPropertyNameResolver(), Formatting = Formatting.Indented // 可选,格式化输出便于查看 }; string json = JsonConvert.SerializeObject(person, settings);
最终序列化结果
生成的JSON会自动替换指定属性的名称:
{ "Name": "John", "Age": 30, "PostalAddress": { "Nmb": "123", "Str": "Main St", "City": "New York", "Country": "USA" } }
补充说明
- 该方案无需修改第三方类代码,所有映射规则集中管理,便于维护调整。
- 若需更复杂的命名逻辑(如动态生成名称),可扩展
ResolvePropertyName或重写CreateProperty方法实现。 - 若使用System.Text.Json(.NET Core 3.0+),可通过自定义
JsonNamingPolicy或JsonConverter实现类似效果,核心思路均为动态指定属性名而非修改类特性。
内容的提问来源于stack exchange,提问作者ozziem
相关产品推荐
相关产品推荐

