You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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; }
}

需要支持两种序列化结果:

  1. 保留注解指定名称:
{
    "fname": "John",
    "lname": "Doe",
    "years_old": 25
}
  1. 忽略注解,使用属性全小写名称:
{
    "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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 07:17:37