ASP.NET中动态添加PartialView时的表单验证异常问题
解决ASP.NET动态添加联系人字段的验证异常问题
问题根源
动态添加的PartialView中,asp-for生成的name和id属性重复,导致jQuery Validate将所有同name的字段视为同一组,单个字段验证失败时所有同组字段都会触发错误提示;同时新添加的控件未被纳入客户端验证体系。
解决方案
1. 修改后端Action,传递唯一索引
在PatientController的DisplayNewContact方法中接收前端传递的索引值,用于生成唯一的字段标识:
public IActionResult DisplayNewContact(string index) { ViewBag.Index = index; return PartialView("_ContactsPartial", new ContactModel()); }
2. 更新PartialView,生成唯一的字段属性
修改_ContactsPartial.cshtml,手动指定唯一的name、id和验证消息关联属性,确保每个联系人字段独立:
@model Vital365.Models.ContactModel @{ var index = ViewBag.Index; } <div class="d-flex mb-2 contact-item" data-index="@index"> <div class="me-2"> <label for="Contacts_@index__Ddd">DDD</label> <input type="number" class="form-control" asp-for="@Model.Ddd" name="Contacts[@index].Ddd" id="Contacts_@index__Ddd"> <span asp-validation-for="@Model.Ddd" class="text-danger" data-valmsg-for="Contacts[@index].Ddd" /> </div> <div class="me-2"> <label for="Contacts_@index__PhoneNumber">Número</label> <input type="number" class="form-control" asp-for="@Model.PhoneNumber" name="Contacts[@index].PhoneNumber" id="Contacts_@index__PhoneNumber"> <span asp-validation-for="@Model.PhoneNumber" class="text-danger" data-valmsg-for="Contacts[@index].PhoneNumber" /> </div> <div> <label for="Contacts_@index__ContactName">Nome</label> <input class="form-control" asp-for="@Model.ContactName" name="Contacts[@index].ContactName" id="Contacts_@index__ContactName"> <span asp-validation-for="@Model.ContactName" class="text-danger" data-valmsg-for="Contacts[@index].ContactName" /> </div> <div> <button type="button" class="btn btn-danger ms-2 mt-4 deleteContact"> <i class="bi bi-trash"></i> </button> </div> </div>
3. 修改Ajax代码,传递索引并重新注册验证
更新前端Ajax调用,传递当前已有联系人数量作为新索引,并在添加后重新解析验证规则:
$(document).on('click', '#addPhoneContact', function (e) { // 获取当前联系人数量作为新索引 var index = $('.contact-item').length; $.ajax({ url: '/Patient/DisplayNewContact', data: { index: index }, success: function (partialView) { $('.ContactsFieldClass').append(partialView); // 重新解析表单验证规则,纳入新控件 var form = $('form')[0]; $.validator.unobtrusive.parse(form); } }); });
4. 处理删除逻辑(可选)
如果需要删除联系人后保持索引连续,添加删除事件处理并更新字段属性:
$(document).on('click', '.deleteContact', function (e) { $(this).closest('.contact-item').remove(); // 重新整理剩余联系人的索引 $('.contact-item').each(function(newIndex) { var $item = $(this); $item.attr('data-index', newIndex); // 更新DDD字段 var $ddd = $item.find('input[name*="Ddd"]'); $ddd.attr({ name: `Contacts[${newIndex}].Ddd`, id: `Contacts_${newIndex}__Ddd` }); $item.find('span[data-valmsg-for*="Ddd"]').attr('data-valmsg-for', `Contacts[${newIndex}].Ddd`); // 更新PhoneNumber字段 var $phone = $item.find('input[name*="PhoneNumber"]'); $phone.attr({ name: `Contacts[${newIndex}].PhoneNumber`, id: `Contacts_${newIndex}__PhoneNumber` }); $item.find('span[data-valmsg-for*="PhoneNumber"]').attr('data-valmsg-for', `Contacts[${newIndex}].PhoneNumber`); // 更新ContactName字段 var $name = $item.find('input[name*="ContactName"]'); $name.attr({ name: `Contacts[${newIndex}].ContactName`, id: `Contacts_${newIndex}__ContactName` }); $item.find('span[data-valmsg-for*="ContactName"]').attr('data-valmsg-for', `Contacts[${newIndex}].ContactName`); }); // 重新解析验证规则 var form = $('form')[0]; $.validator.unobtrusive.parse(form); });
5. 确保模型定义正确
验证Patient模型包含Contacts集合,且ContactModel设置了正确的验证属性:
public class PatientModel { // 其他属性 public List<ContactModel> Contacts { get; set; } = new List<ContactModel>(); } public class ContactModel { [Required(ErrorMessage = "DDD é obrigatório")] public string Ddd { get; set; } [Required(ErrorMessage = "Número é obrigatório")] public string PhoneNumber { get; set; } [Required(ErrorMessage = "Nome é obrigatório")] public string ContactName { get; set; } }
原理说明
- 唯一的
name属性让jQuery Validate将每个字段视为独立验证单元,避免批量触发错误。 $.validator.unobtrusive.parse(form)重新解析表单,使新添加的控件被客户端验证框架识别。- 符合ASP.NET模型绑定规则,提交表单时后端能正确接收Contacts集合数据。
内容的提问来源于stack exchange,提问作者Pedro William
相关产品推荐
相关产品推荐

