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

Blazor中Virtualize结合EditForm与FluentValidation的全量验证问题

解决方案思路

核心问题拆解

Virtualize仅渲染可见行,导致绑定到EditContext的FluentValidation(EFV)只能验证已渲染的行;全量验证需要脱离EditContext的渲染依赖,直接验证数据集,同时要在滚动渲染行时同步错误状态。

具体实现步骤

1. 脱离EditContext,手动执行全量验证

直接使用FluentValidation的Validator实例对整个数据集进行验证,不依赖EditForm的渲染上下文:

  • 创建Validator实例,遍历所有数据项逐个验证,将错误存入全局字典(用数据项唯一ID作为键):
    // 全局存储所有数据项的验证错误
    private Dictionary<int, List<ValidationFailure>> _validationErrors = new();
    
    public async Task ValidateAllItems()
    {
        _validationErrors.Clear();
        var validator = new YourItemValidator();
        foreach (var item in YourDataset)
        {
            var result = await validator.ValidateAsync(item);
            if (!result.IsValid)
            {
                _validationErrors[item.Id] = result.Errors.ToList();
            }
        }
        // 通知UI更新错误状态
        StateHasChanged();
    }
    

2. 滚动渲染时同步错误到行组件

在Virtualize渲染的行组件中,将全局错误字典中的错误同步到当前行的EditContext:

  • 行组件接收数据项和错误字典作为参数,初始化或参数更新时手动同步错误:
    @using FluentValidation.Results
    @using Microsoft.AspNetCore.Components.Forms
    
    <EditForm EditContext="_editContext">
        <InputText @bind-Value="Item.Name" />
        <ValidationMessage For="@(() => Item.Name)" />
        <!-- 其他表单控件 -->
    </EditForm>
    
    @code {
        [Parameter] public YourItem Item { get; set; }
        [Parameter] public Dictionary<int, List<ValidationFailure>> ValidationErrors { get; set; }
        private EditContext _editContext;
        private ValidationMessageStore _messageStore;
    
        protected override void OnInitialized()
        {
            _editContext = new EditContext(Item);
            _messageStore = new ValidationMessageStore(_editContext);
            SyncValidationErrors();
        }
    
        protected override void OnParametersSet()
        {
            SyncValidationErrors();
        }
    
        private void SyncValidationErrors()
        {
            _messageStore.Clear();
            if (ValidationErrors.TryGetValue(Item.Id, out var errors))
            {
                foreach (var error in errors)
                {
                    _messageStore.Add(_editContext.Field(error.PropertyName), error.ErrorMessage);
                }
            }
            _editContext.NotifyValidationStateChanged();
        }
    }
    

3. 行内数据修改时实时更新错误

在行组件中,当数据项发生变化时,实时验证并更新全局错误字典:

[Parameter] public EventCallback<YourItem> OnItemUpdated { get; set; }

private async Task OnItemChanged()
{
    var validator = new YourItemValidator();
    var result = await validator.ValidateAsync(Item);
    
    if (ValidationErrors.ContainsKey(Item.Id))
    {
        ValidationErrors.Remove(Item.Id);
    }
    if (!result.IsValid)
    {
        ValidationErrors[Item.Id] = result.Errors.ToList();
    }
    
    await OnItemUpdated.InvokeAsync(Item);
}

替代方案

如果上述EFV手动验证方式不符合需求,可考虑:

  • DataAnnotations手动验证:通过Validator.TryValidateObject遍历数据集,将错误存入全局字典,后续同步逻辑与上述一致。
  • 自定义验证服务:封装独立于UI的验证逻辑,直接对数据集进行验证并返回错误集合,由UI层根据错误集合渲染状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 00:27:27