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

FluentValidation条件验证子属性:仅HasDetails为true时验证子模型?

问题描述

我希望仅当父对象PersonDetailsViewModel的HasDetails属性为true时,才对复杂子属性BasicDetails进行验证。

我的视图模型定义如下:

public class PersonDetailsViewModel
{
    public bool? HasDetails { get; set; }
    public BasicDetailsViewModel? BasicDetails { get; set; }
}

BasicDetailsViewModel的定义:

public class BasicDetailsViewModel
{
    public string? FirstName { get; set; }
    public string? Country { get; set; }
}

我为PersonDetailsViewModel编写的验证器PersonDetailsViewModelValidator代码如下:

public class PersonDetailsViewModelValidator : AbstractValidator<PersonDetailsViewModel>
{
    public PersonDetailsViewModelValidator()
    {
         RuleFor(model => model.BasicDetails)
           .SetValidator(new BasicDetailsViewModelValidator())
           .When(model => model.HasDetails == true);
    }
}

BasicDetailsViewModelValidator的代码:

public class BasicDetailsViewModelValidator : AbstractValidator<BasicDetailsViewModel?>
{
    public BasicDetailsViewModelValidator()
    {
        RuleFor(model => model.FirstName)
            .NotEmpty().WithMessage(ValidationMessages.Required);

        RuleFor(model => model.Country)
            .NotEmpty().WithMessage(ValidationMessages.Required);
    }
}

我在BasicDetailsViewModelValidator的构造函数中设置了断点,但无论HasDetails的值是什么,只要PersonDetailsViewModelValidator被调用,断点就会触发。我原本预期只有当HasDetails为true时才会触发该断点。请问我是否操作有误,还是这是预期行为?


解答

这是预期行为,你混淆了「验证器实例化」和「验证规则执行」的时机:

  • 当PersonDetailsViewModelValidator的构造函数执行时,你直接new BasicDetailsViewModelValidator()创建了子验证器实例,此时子验证器的构造函数会立即执行——这是验证器的规则初始化阶段,和When条件无关。
  • When(model => model.HasDetails == true)控制的是子验证器的规则是否会被应用到目标对象上,而非子验证器是否被实例化。也就是说,只有当HasDetails为true时,BasicDetails的FirstName和Country非空规则才会实际执行验证;但子验证器的构造函数在父验证器初始化时就已经运行完成了。

如果要验证逻辑是否符合预期,建议在BasicDetailsViewModelValidator的规则逻辑(比如NotEmpty()的执行环节)添加断点,而非构造函数中。此时你会发现:当HasDetails为false时,这些规则断点不会触发;只有HasDetails为true时,才会进入子验证器的规则执行流程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 05:32:18