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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 16:12:37