.NET 6中使用System.Text.Json序列化时忽略JsonPropertyName的方法
在.NET 6中让System.Text.Json忽略JsonPropertyName注解的方案
问题场景
在.NET 6项目中使用System.Text.Json序列化时,部分数据类通过[JsonPropertyName]注解指定了属性的序列化名称以对接外部API,但现在业务需要另一种场景——使用**属性原名(全小写形式)**进行序列化,且因类属性较多,不想编写大量DTO,也无法切换回Newtonsoft.Json。
示例类定义:
public class Account { [JsonPropertyName("fname")] public string FirstName { get; set; } [JsonPropertyName("lname")] public string LastName { get; set; } [JsonPropertyName("years_old")] public int Age {get; set; } }
需要支持两种序列化结果:
- 保留注解指定名称:
{ "fname": "John", "lname": "Doe", "years_old": 25 }
- 忽略注解,使用属性全小写名称:
{ "firstname": "John", "lastname": "Doe", "age": 25 }
解决方案:自定义JsonTypeInfoResolver
System.Text.Json中可以通过自定义DefaultJsonTypeInfoResolver来实现类似Newtonsoft.Json中ContractResolver的功能,通过修改类型信息生成逻辑,忽略[JsonPropertyName]注解的影响。
1. 实现自定义Resolver
using System.Text.Json; using System.Text.Json.Serialization; using System.Reflection; public class IgnoreJsonPropertyNameResolver : DefaultJsonTypeInfoResolver { protected override void ModifyTypeInfo(JsonTypeInfo typeInfo) { base.ModifyTypeInfo(typeInfo); // 仅处理对象类型 if (typeInfo.Kind != JsonTypeInfoKind.Object) return; foreach (var property in typeInfo.Properties) { // 获取属性的原始名称 var originalPropName = property.PropertyInfo?.Name ?? property.Name; // 将属性名转换为全小写(可根据需求调整命名规则) property.Name = originalPropName.ToLowerInvariant(); // 移除JsonPropertyName注解的影响 var jsonPropAttr = property.GetCustomAttribute<JsonPropertyNameAttribute>(); if (jsonPropAttr != null) { property.Attributes.Remove(jsonPropAttr); } } } }
2. 两种场景的使用方式
场景1:保留[JsonPropertyName]注解的序列化
直接使用默认的JsonSerializerOptions即可:
var account = new Account { FirstName = "John", LastName = "Doe", Age = 25 }; var defaultOptions = new JsonSerializerOptions(); string jsonWithAnnotation = JsonSerializer.Serialize(account, defaultOptions); // 输出:{"fname":"John","lname":"Doe","years_old":25}
场景2:忽略[JsonPropertyName]注解的序列化
使用自定义的Resolver配置JsonSerializerOptions:
var ignoreAttrOptions = new JsonSerializerOptions { TypeInfoResolver = new IgnoreJsonPropertyNameResolver() }; string jsonWithoutAnnotation = JsonSerializer.Serialize(account, ignoreAttrOptions); // 输出:{"firstname":"John","lastname":"Doe","age":25}
原理说明
DefaultJsonTypeInfoResolver是System.Text.Json负责生成类型序列化元信息的核心组件,重写其ModifyTypeInfo方法可以在元信息生成后,对每个属性的配置进行修改:
- 通过覆盖
property.Name指定新的序列化名称; - 移除
JsonPropertyNameAttribute,确保原注解不再生效。
这种方式无需修改原有数据类,也不需要编写DTO,可复用Resolver处理所有需要忽略注解的序列化场景。
内容的提问来源于stack exchange,提问作者Isu
相关产品推荐
相关产品推荐

