如何在ASP.NET Core 9 Web API中全局拒绝非可空引用类型的Null值
解决ASP.NET Core 9中非可空引用类型required属性的提前验证问题
内置配置优化
你当前的基础配置已覆盖核心设置,但针对required仅初始化属性,需补充System.Text.Json的反序列化规则,确保缺失字段或传入null时直接触发异常,而非进入属性setter:
services.AddControllers(opts => { opts.SuppressImplicitRequiredAttributeForNonNullableReferenceTypes = false; }) .AddJsonOptions(opts => { opts.JsonSerializerOptions.RespectNullableAnnotations = true; opts.JsonSerializerOptions.RespectRequiredConstructorParameters = true; // 强制要求所有required成员必须存在且非null opts.JsonSerializerOptions.RequiredMemberHandling = JsonRequiredMemberHandling.Always; opts.JsonSerializerOptions.PropertyNameCaseInsensitive = true; // 保持接口大小写兼容(可选) });
JsonRequiredMemberHandling.Always会让System.Text.Json在反序列化时,对标记为required的成员强制检查存在性与非空性,不满足则抛出JsonException,ASP.NET Core会自动将其转换为HTTP 400响应。
自定义全局模型验证器
若内置配置无法覆盖所有非可空引用类型的验证场景(比如未标记required但本身是非可空的引用类型属性),可实现自定义验证器全局生效:
1. 实现验证器逻辑
public class NonNullableReferenceValidator : IModelValidator { public IEnumerable<ModelValidationResult> Validate(ModelValidationContext context) { var modelMeta = context.ModelMetadata; // 跳过值类型与可空引用类型 if (modelMeta.ModelType.IsValueType || modelMeta.IsReferenceOrNullableType) yield break; // 检查属性值是否为null if (context.Model == null) { yield return new ModelValidationResult( string.Empty, $"属性「{modelMeta.DisplayName}」不能为空"); } // 针对required属性补充缺失检查 if (modelMeta.IsRequired && context.Model == null) { yield return new ModelValidationResult( string.Empty, $"必填属性「{modelMeta.DisplayName}」未提供或值为null"); } } }
2. 注册验证器提供者
public class NonNullableValidationProvider : IModelValidatorProvider { public void CreateValidators(ModelValidatorProviderContext context) { // 为所有非可空引用类型的模型添加验证器 var modelMeta = context.ModelMetadata; if (!modelMeta.ModelType.IsValueType && !modelMeta.IsReferenceOrNullableType) { context.Validators.Add(new NonNullableReferenceValidator()); } } }
3. 全局注册
在Program.cs的控制器配置中添加:
services.AddControllers(opts => { opts.SuppressImplicitRequiredAttributeForNonNullableReferenceTypes = false; opts.ModelValidatorProviders.Add(new NonNullableValidationProvider()); }) // 保留原Json配置 .AddJsonOptions(opts => { /* 配置内容同上 */ });
社区包推荐:FluentValidation
如果需要更灵活的验证扩展能力,可使用FluentValidation,它能自动识别非可空引用类型并添加默认必填规则:
1. 安装依赖
Install-Package FluentValidation.AspNetCore
2. 全局配置
在Program.cs中注册:
services.AddFluentValidationAutoValidation() .AddFluentValidationClientsideAdapters(); // 自动扫描当前程序集内的DTO并添加默认验证规则 services.AddValidatorsFromAssemblyContaining<CreateUserRequest>();
默认情况下,FluentValidation会自动验证所有非可空引用类型属性不能为null,required属性必须存在,无需额外编写规则。
最终效果
以上方案均可实现:
- 客户端提交
"UserName": null或省略该字段时,直接返回HTTP 400响应 - 无需修改现有DTO结构(不用全部转为构造函数绑定的记录)
- 全局生效,无需逐个添加
[Required]属性
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

