如何在Blazor EditForm中为List属性的特定项添加ValidationMessage
Blazor Server中EditForm验证List子项并显示单个输入框验证消息的解决方案
核心问题分析
你当前的代码存在两个关键问题,导致单个输入框旁无法显示验证消息:
- 父模型
Validate方法中索引变量i的递增位置错误,所有子项的索引都会被设为0,验证框架无法匹配到正确的字段路径。 - Razor组件中使用
foreach遍历子项时,ValidationMessage的For表达式无法生成指向父模型带索引的字段路径,导致验证消息无法关联到单个输入框。
修正后的代码实现
1. 父模型类(修正索引逻辑)
public class ParentItemModel : IValidatableObject { public List<ChildItemModel> ChildItems { get; set; } = new List<ChildItemModel>(); public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { var results = new List<ValidationResult>(); if (ChildItems != null) { // 使用for循环确保索引正确递增 for (int i = 0; i < ChildItems.Count; i++) { var item = ChildItems[i]; if (string.IsNullOrEmpty(item.Data)) { // 正确设置成员名称路径:ChildItems[索引].Data results.Add(new ValidationResult("必填字段", new[] { $"ChildItems[{i}].Data" })); } } } return results; } }
2. 子模型类(无需修改)
public class ChildItemModel { public string Data { get; set; } = ""; }
3. Razor组件(改用for循环绑定字段)
<EditForm Model="@ParentItem" OnValidSubmit="@HandleValidSubmit"> <DataAnnotationsValidator /> <ValidationSummary /> <div> @for (int i = 0; i < ParentItem.ChildItems.Count; i++) { var index = i; // 捕获索引变量,避免循环变量捕获问题 <div> <input type="text" @bind="@ParentItem.ChildItems[index].Data" /> <ValidationMessage For="@(() => ParentItem.ChildItems[index].Data)" /> </div> } </div> <button type="submit" class="btn btn-primary">提交</button> </EditForm> @code { private ParentItemModel ParentItem { get; set; } = new ParentItemModel { ChildItems = new List<ChildItemModel> { new ChildItemModel(), new ChildItemModel() } }; private void HandleValidSubmit() { // 自定义提交逻辑 } }
关键修正说明
- 父模型索引修正:将
foreach改为for循环,确保每个子项的索引i正确递增,生成的ChildItems[i].Data路径能被验证框架正确识别。 - Razor循环方式修正:用
for循环替代foreach,并通过var index = i捕获索引变量,让ValidationMessage的For表达式生成准确的字段路径,使验证消息能绑定到对应的输入框旁显示。
内容的提问来源于stack exchange,提问作者redrobot
相关产品推荐
相关产品推荐

