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

FluentValidation中属性为Null时SetValidator未触发的问题咨询

这确实是FluentValidation的设计预期

FluentValidation默认会跳过对null属性的子验证器调用,核心原因有两点:

  • 避免潜在的空引用异常,毕竟很多验证逻辑依赖属性的非空状态
  • 遵循"显式声明必填性"的设计原则:框架认为属性是否为必填是父验证器的职责,子验证器只负责验证非空状态下的属性规则

如果你想让自定义验证器自己处理null场景,有两种可行方案:

方案1:重写自定义验证器的PreValidate方法

默认的PreValidate会在属性值为null时返回false,直接跳过后续验证逻辑。重写这个方法让它始终返回true,就能强制执行自定义验证器里的所有规则,包括空值校验:

public class BankRoutingNumberValidator : AbstractValidator<string?>
{
    public BankRoutingNumberValidator()
    {
        // 包含null和空字符串的校验
        RuleFor(x => x).NotNull().WithMessage("路由编号不能为null");
        RuleFor(x => x).NotEmpty().WithMessage("路由编号不能为空字符串");
        RuleFor(x => x).Length(9).WithMessage("路由编号必须为9位");
        // 格式、校验和等其他规则...
    }

    protected override bool PreValidate(ValidationContext<string?> context, ValidationResult result)
    {
        // 强制执行所有验证规则,无论值是否为null
        return true;
    }
}

方案2:在父验证器中使用CascadeMode调整验证行为

如果不想修改自定义验证器,可以在父验证器的规则链中设置CascadeMode.Continue,结合NotNull()和子验证器,不过这种方式还是需要在父验证器声明必填性,只是能确保后续验证执行:

RuleFor(payment => payment.RoutingNumber)
    .Cascade(CascadeMode.Continue)
    .NotNull()
    .SetValidator(new BankRoutingNumberValidator());

但显然方案1更符合你的需求——让自定义验证器完全接管包括空值在内的所有校验逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 16:48:17