如何让属性的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的模型绑定配置中为目标属性添加转换器,从根源避免全局生效:
- 移除属性上的转换器标记:
public class MyClass { public string MyProperty { get; set;} }
- 在
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
相关产品推荐
相关产品推荐

