可空Uuid值类型自定义JsonConverter未被调用问题排查求助
问题诱因
- 核心原因:你标记了
[FromQuery]的参数走ASP.NET Core原生的查询参数模型绑定逻辑,和AddJsonOptions中配置的JSON序列化规则是两套完全独立的体系,你注册的JsonConverter只对JSON格式的请求/响应Body生效,完全不会参与查询参数的类型转换。 - 补充场景(如果是JSON Body请求仍有问题):你实现了两套转换器反而引发了匹配冲突,System.Text.Json处理可空值类型时会优先复用对应非可空类型的转换器,同时你的注册顺序也会干扰匹配逻辑,另外单独写可空转换器本身属于冗余实现,System.Text.Json原生支持自动包装非可空值类型的转换器适配可空场景。
解决方案
方案1:适配查询参数绑定场景(适用于确实需要从URL传参的场景)
给你的Uuid值类型注册全局TypeConverter,即可同时兼容可空/非可空场景的查询参数绑定、路由参数绑定:
// 直接把特性加在Uuid类/结构体定义上即可 [TypeConverter(typeof(UuidTypeConverter))] public struct Uuid { // 原有实现不变 } public class UuidTypeConverter : TypeConverter { public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); } public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value is string str && Uuid.TryParse(str, out var uuid)) { return uuid; } return base.ConvertFrom(context, culture, value); } }
如果你的Uuid类型已经实现了IParsable<Uuid>接口(.NET 7+支持),则不需要额外写TypeConverter,ASP.NET Core会自动识别处理可空/非可空场景的查询参数绑定。
方案2:统一走JSON Body传参(适用于参数不需要暴露在URL的场景)
- 删掉请求模型上的
[FromQuery]标记,或者换成[FromBody]标记,将参数放到请求Body中用JSON格式传输 - 删掉冗余的
NullableUuidJsonConverter实现和注册逻辑,只保留UuidJsonConverter即可,System.Text.Json会自动兼容Uuid?可空场景的序列化/反序列化:
.AddJsonOptions(options => { options.JsonSerializerOptions.Converters.Add(new UuidJsonConverter()); });
内容的提问来源于stack exchange,提问作者Fallingsappy
相关产品推荐
相关产品推荐

