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

如何让属性的JsonConverter仅在Web API模型绑定时生效?

问题与解决方案:自定义JsonConverter仅在模型绑定阶段生效

问题场景

Web API的POST: /api/Partition接口接收如下JSON结构:

{
    // myProperty 为字符串数组
    "myProperty": ["a", "b"]
}

但控制器Action接收的MyClass类中,MyProperty是string类型:

[HttpPost]
public ActionResult<MyClass> Post(MyClass postObject)
{
    // 业务逻辑
}

public class MyClass 
{
    public string MyProperty { get; set;}
}

为了实现数组转字符串的转换,编写了StringToStringArrayJsonConverter并通过[JsonConverter]特性注册到MyProperty上,但该转换器会在手动调用JsonSerializer.Serialize()/JsonSerializer.Deserialize()时也生效,不符合需求——希望它仅在控制器模型绑定阶段起作用。


解决方案

方案1:手动序列化时忽略属性上的转换器(.NET 7+)

.NET 7及以上版本的JsonSerializerOptions新增了IgnoreJsonConverterAttributes属性,设置为true即可忽略所有属性上标记的[JsonConverter]特性,仅在手动序列化/反序列化时使用该配置:

// 手动序列化专用配置
var serializeOptions = new JsonSerializerOptions
{
    IgnoreJsonConverterAttributes = true,
    PropertyNameCaseInsensitive = true // 保持与Web API默认配置一致
};

// 序列化示例
var json = JsonSerializer.Serialize(myClassInstance, serializeOptions);

// 反序列化示例
var obj = JsonSerializer.Deserialize<MyClass>(json, serializeOptions);

方案2:自定义ContractResolver移除特定转换器(兼容旧版本)

针对.NET 7以下版本,可通过自定义JsonTypeInfoResolver移除目标属性上的指定转换器:

public class IgnoreSpecificConverterResolver : DefaultJsonTypeInfoResolver
{
    private readonly Type _targetConverterType;

    public IgnoreSpecificConverterResolver(Type targetConverterType)
    {
        _targetConverterType = targetConverterType;
    }

    public override JsonTypeInfo GetTypeInfo(Type type, JsonSerializerOptions options)
    {
        var typeInfo = base.GetTypeInfo(type, options);
        // 遍历属性,移除指定类型的转换器
        foreach (var property in typeInfo.Properties)
        {
            property.Converters.RemoveAll(c => c.GetType() == _targetConverterType);
        }
        return typeInfo;
    }
}

// 使用方式
var serializeOptions = new JsonSerializerOptions
{
    TypeInfoResolver = new IgnoreSpecificConverterResolver(typeof(StringToStringArrayJsonConverter)),
    PropertyNameCaseInsensitive = true
};

// 序列化/反序列化时传入该配置
var json = JsonSerializer.Serialize(myClassInstance, serializeOptions);

方案3:仅在模型绑定配置中注册转换器(根源解决)

移除MyClass属性上的[JsonConverter]特性,改为仅在Web API的模型绑定配置中为目标属性添加转换器,从根源避免全局生效:

  1. 移除属性上的转换器标记:
public class MyClass 
{
    public string MyProperty { get; set;}
}
  1. 在Program.cs(或Startup.cs)中配置Web API的Json选项:
builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.TypeInfoResolver = new DefaultJsonTypeInfoResolver
        {
            Modifiers = {
                typeInfo =>
                {
                    // 仅为MyClass的MyProperty添加转换器
                    if (typeInfo.Type == typeof(MyClass))
                    {
                        var targetProperty = typeInfo.Properties
                            .FirstOrDefault(p => p.Name == nameof(MyClass.MyProperty));
                        if (targetProperty != null)
                        {
                            targetProperty.Converters.Add(new StringToStringArrayJsonConverter());
                        }
                    }
                }
            }
        };
    });

此方式下,只有Web API的模型绑定流程会使用该转换器,手动调用JsonSerializer时默认配置不会包含它,自然不会生效。


内容的提问来源于stack exchange,提问作者Sharon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 11:53:17