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

如何在依赖属性值变更时触发Fluent Validation验证?

问题:依赖属性的Fluent Validation实时验证不触发

我有一个依赖于A、B、C、D、E五个布尔属性的计算属性AnyLetter,Fluent Validation在表单提交时能正常验证,但希望它像Location属性一样,在值变更时实时触发验证——目前修改复选框时,AnyLetter的错误消息不会自动消失,而修改Location时错误会即时消失。


视图模型

public record AlphabetViewModel
{
    public bool AddDate { get; set; }
    public bool A { get; set; }
    public bool B { get; set; }
    public bool C { get; set; }
    public bool D { get; set; }
    public bool E { get; set; }
    public bool AnyLetter => A || B || C || D || E;
    public string Location { get; set; }
}

Fluent验证器

public class AlphabetViewModelValidator : AbstractValidator<AlphabetViewModel>
{
    public AlphabetViewModelValidator()
    {
        When(x => x.AddDate, () =>
        {
            RuleFor(x => x.Location).NotEmpty().WithMessage("Location是必填字段。");
            RuleFor(x => x.AnyLetter).NotEqual(false).WithMessage("至少需要选择一个字母。");
        });
    }
}

UI代码

<div class="row">
    <div class="col-md-6 col-sm-6">
        <label for="Location">Location*</label>
        <SfTextBox Enabled="true" ID="Location" Placeholder="输入内容" maxlength="100" TabIndex="10"
                   @bind-Value="AlphabetViewModel.Location"/>
        <ValidationMessage For="@(()=> AlphabetViewModel.Location)" />
    </div>
</div>
<div class="row">
    <div class="col-md-3 col-sm-3">
        <label for="AnyLetter">Any Letter*</label>
        <ValidationMessage For="@(()=> AlphabetViewModel.AnyLetter)" />
    </div>
</div>
<div class="row">
    <div class="col-md-2 col-sm-2">
        <label for="A">A</label>
        <SfCheckBox id="A" TChecked="bool" TabIndex="12" @bind-Checked="AlphabetViewModel.A"/>
    </div>
    <div class="col-md-2 col-sm-2">
        <label for="B">B</label>
        <SfCheckBox id="B" TChecked="bool" TabIndex="13" @bind-Checked="AlphabetViewModel.B"/>
    </div>
    <div class="col-md-2 col-sm-2">
        <label for="C">C</label>
        <SfCheckBox id="C" TChecked="bool" TabIndex="14" @bind-Checked="AlphabetViewModel.C"/>
    </div>
    <div class="col-md-2 col-sm-2">
        <label for="D">D</label>
        <SfCheckBox id="D" TChecked="bool" TabIndex="15" @bind-Checked="AlphabetViewModel.D"/>
    </div>
    <div class="col-md-2 col-sm-2">
        <label for="E">E</label>
        <SfCheckBox id="E" TChecked="bool" TabIndex="16" @bind-Checked="AlphabetViewModel.E"/>
    </div>
</div>

已尝试的无效方案

// 方案1:直接判断字母状态
When(x => (x.A || x.B || x.C || x.D || x.E) == false, () =>
{
    RuleFor(x => x.AnyLetter).NotEqual(false).WithMessage("至少需要选择一个字母。");
});

// 方案2:使用DependentRules
RuleFor(x => x.AnyLetter).NotEqual(false).DependentRules(() =>
{
    RuleFor(x => x.A).NotEqual(false);
    RuleFor(x => x.B).NotEqual(false);
    RuleFor(x => x.C).NotEqual(false);
    RuleFor(x => x.D).NotEqual(false);
    RuleFor(x => x.E).NotEqual(false);

}).WithMessage("至少需要选择一个字母。");

解决方法

问题核心是:Blazor的ValidationMessage组件默认只监听绑定属性的变更,而AnyLetter是计算属性,当A-E变更时,Blazor不会自动触发AnyLetter的验证重新执行。以下是两种可行的解决思路:

1. 调整验证规则,直接验证依赖属性

把针对AnyLetter的验证改成针对整个模型的条件验证,同时指定错误关联到AnyLetter,这样任一复选框变更时都会触发验证:

public class AlphabetViewModelValidator : AbstractValidator<AlphabetViewModel>
{
    public AlphabetViewModelValidator()
    {
        When(x => x.AddDate, () =>
        {
            RuleFor(x => x.Location).NotEmpty().WithMessage("Location是必填字段。");
            
            // 直接验证至少一个字母被选中,关联到AnyLetter的验证消息
            RuleFor(x => x)
                .Must(x => x.A || x.B || x.C || x.D || x.E)
                .WithMessage("至少需要选择一个字母。")
                .WithName("AnyLetter");
        });
    }
}

2. 复选框变更时手动触发验证

在Blazor组件中注入EditContext,给每个复选框添加ValueChanged事件,触发全局验证:

<!-- 以A复选框为例,其他复选框同理 -->
<SfCheckBox id="A" TChecked="bool" TabIndex="12" 
            @bind-Checked="AlphabetViewModel.A"
            ValueChanged="@(() => EditContext.Validate())"/>

推荐组合

优先使用调整验证规则+手动触发验证的方案,无需修改视图模型的结构,就能实现和Location一致的实时验证效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 07:04:58