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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 18:55:23