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

如何在嵌套Blazor EditForm中实现表单验证?

解决Blazor嵌套集合表单验证失效问题

你的问题核心在于默认的DataAnnotationsValidator不会递归验证集合内的子对象,且嵌套EditForm会破坏外层EditContext的统一验证状态。以下是具体解决步骤:

1. 启用对象图递归验证

将外层EditForm中的DataAnnotationsValidator替换为ObjectGraphDataAnnotationsValidator,它支持遍历验证对象的所有嵌套属性(包括集合元素):

<div>
    <EditForm Model="person" OnValidSubmit="CreateNewPerson">
        <!-- 替换为支持递归验证的组件 -->
        <ObjectGraphDataAnnotationsValidator />

        <div>
            <label for="name">Name</label>
            <InputText id="name" @bind-Value="person.Name" />
            <ValidationMessage For="@(() => person.Name)" />
        </div>
        <div>
            <label for="age">Age</label>
            <InputNumber id="age" @bind-Value="person.Age" />
        </div>
        <div>
            <label>Addresses</label>
            <!-- 传递外层EditContext给子组件 -->
            <AddressEditor Addresses="person.Addresses" EditContext="@EditContext" />
        </div>
        <div>
            <button type="submit">Create</button>
        </div>
                
        <ValidationSummary />
    </EditForm>
</div>

@code{
    private Person person = new();
    
    private async Task CreateNewPerson()
    {
     // ... 提交逻辑
    }
}

同时修复实体类语法错误并初始化集合:

public class Person
{
    [Required]
    public string Name { get; set; }
    public int Age { get; set; }

    public List<Address> Addresses { get; set; } = new List<Address>();
}

public class Address
{
    [Required(ErrorMessage = "Street is required")]
    public string Street { get; set; }
}

2. 重构AddressEditor组件

移除嵌套的EditForm,共用外层传递的EditContext,并添加验证错误提示:

<div>
    <button type="button" @onclick="AddNewAddress">Add</button>
</div>

@for (var i = 0; i < Addresses.Count; i++)
{
    var index = i; // 捕获循环变量,避免Blazor渲染歧义
    <div>
        <label>Street @(index + 1)</label>
        <InputText @bind-Value="Addresses[index].Street" />
        <!-- 显示当前Address的Street字段验证错误 -->
        <ValidationMessage For="@(() => Addresses[index].Street)" />
    </div>
}

@code{
    [Parameter]
    public List<Address> Addresses { get; set; } = new();
    
    [Parameter]
    public EditContext? EditContext { get; set; }

    private void AddNewAddress()
    {
        Addresses.Add(new Address());
        // 通知EditContext模型状态变化,触发重新验证
        EditContext?.NotifyValidationStateChanged();
    }
}

关键修改说明

  • ObjectGraphDataAnnotationsValidator:替代默认验证组件,实现对集合、嵌套对象的递归验证,确保每个Address的Required属性被检测。
  • 共用EditContext:子组件不再创建独立EditForm,直接使用外层传递的EditContext,保证验证状态统一。
  • 捕获循环变量:Blazor循环渲染时必须捕获index变量,否则所有Input会绑定到最后一个元素的引用。
  • NotifyValidationStateChanged:添加新地址后手动通知验证状态变化,触发UI和验证规则的更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 04:53:10