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

ASP.NET Core表单提交时Controller无法完整接收List属性的问题咨询

解决ASP.NET Core中List集合表单绑定为空的问题

你遇到的问题核心是ASP.NET Core的Model绑定无法识别foreach循环生成的表单控件name属性——默认foreach循环不会为集合项生成带索引的name格式,导致后端只能接收到第一个项或者完全为空。下面给你两种靠谱的解决方法:

方法一:使用for循环代替foreach循环

ASP.NET Core的Model绑定要求集合类型的表单控件name格式为集合属性名[索引].属性名(比如VenueItems[0].IsEventHaveSustainableApproach),而foreach循环无法自动生成这种格式,换成for循环就能解决:

修改View代码:

首先确保你的VenueItems是IList<VenueViewModel>(如果原来用的是List也可以,因为List实现了IList),然后把foreach替换成for循环:

<form method="post" enctype="multipart/form-data" class="form-content-column" id="formFull">
    <div class="input-box">
        <label class="numbered" for="Name">Name<span class="span-mandatory">*</span></label>
        <input asp-for="Name" class="input-mandatory" type="text" id="Name" required />
        <span asp-validation-for="Name"></span>
        <input asp-for="Id" type="hidden" id="Id" required />
    </div>
    <div class="accordion" id="accordionExample">
        @* 替换foreach为for循环 *@
        @for (int i = 0; i < Model.VenueItems.Count; i++) {
            <div class="accordion-item">
                <h2 class="accordion-header" id="headingOne@Model.VenueItems[i].Id">
                    <button class="accordion-button accordion-button-custom" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne_@Model.VenueItems[i].Id" aria-expanded="true" aria-controls="collapseOne_@Model.VenueItems[i].Id" style="margin-top: 0px">
                        @Model.VenueItems[i].VenueName
                    </button>
                </h2>
                <div id="collapseOne_@Model.VenueItems[i].Id" class="accordion-collapse collapse show" aria-labelledby="headingOne_@Model.VenueItems[i].Id" data-bs-parent="#accordionExample">
                    <div class="accordion-body">
                        <div class="input-box no-border">
                            <label class="numbered">Did the venue have a sustainable approach?<span class="span-mandatory">*</span></label>
                            <div class="flex flex-column">
                                <div class="single-radio">
                                    @* 用集合索引的方式绑定asp-for *@
                                    <input asp-for="VenueItems[i].IsEventHaveSustainableApproach" class="input-mandatory radio_Tab1_IsEventHaveSustainableApproach" type="radio" value="1" id="Tab1_IsEventHaveSustainableApproach_Yes_@Model.VenueItems[i].Id" />
                                    <label for="Tab1_IsEventHaveSustainableApproach_Yes_@Model.VenueItems[i].Id">Yes</label>
                                </div>
                                <div class="single-radio">
                                    <input asp-for="VenueItems[i].IsEventHaveSustainableApproach" class="input-mandatory radio_Tab1_IsEventHaveSustainableApproach" type="radio" value="0" id="Tab1_IsEventHaveSustainableApproach_No_@Model.VenueItems[i].Id" />
                                    <label for="Tab1_IsEventHaveSustainableApproach_No_@Model.VenueItems[i].Id">No</label>
                                </div>
                            </div>
                        </div>
                        <div class="input-box">
                            <label for="Tab1_Checkbox_EventVenue_Other_@Model.VenueItems[i].Id">Other? Please explain</label>
                            <input asp-for="VenueItems[i].Checkbox_Other" type="text" id="Tab1_Checkbox_EventVenue_Other_@Model.VenueItems[i].Id" />
                        </div>
                    </div>
                </div>
            </div>
        }
    </div>
</form>

修改后,asp-for会自动生成类似VenueItems[0].IsEventHaveSustainableApproach、VenueItems[1].Checkbox_Other的name属性,后端Model绑定器就能正确识别并填充整个VenueItems列表了。

方法二:使用EditorTemplate(更优雅的方式)

如果你的集合项表单比较复杂,推荐使用EditorTemplate来复用代码,同时自动生成正确的绑定格式:

步骤1:创建EditorTemplate视图

在Views/Shared/EditorTemplates文件夹下创建VenueViewModel.cshtml(文件名必须和模型类名一致),内容如下:

@model VenueViewModel

<div class="accordion-item">
    <h2 class="accordion-header" id="headingOne@Model.Id">
        <button class="accordion-button accordion-button-custom" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne_@Model.Id" aria-expanded="true" aria-controls="collapseOne_@Model.Id" style="margin-top: 0px">
            @Model.VenueName
        </button>
    </h2>
    <div id="collapseOne_@Model.Id" class="accordion-collapse collapse show" aria-labelledby="headingOne_@Model.Id" data-bs-parent="#accordionExample">
        <div class="accordion-body">
            <div class="input-box no-border">
                <label class="numbered">Did the venue have a sustainable approach?<span class="span-mandatory">*</span></label>
                <div class="flex flex-column">
                    <div class="single-radio">
                        <input asp-for="IsEventHaveSustainableApproach" class="input-mandatory radio_Tab1_IsEventHaveSustainableApproach" type="radio" value="1" id="Tab1_IsEventHaveSustainableApproach_Yes_@Model.Id" />
                        <label for="Tab1_IsEventHaveSustainableApproach_Yes_@Model.Id">Yes</label>
                    </div>
                    <div class="single-radio">
                        <input asp-for="IsEventHaveSustainableApproach" class="input-mandatory radio_Tab1_IsEventHaveSustainableApproach" type="radio" value="0" id="Tab1_IsEventHaveSustainableApproach_No_@Model.Id" />
                        <label for="Tab1_IsEventHaveSustainableApproach_No_@Model.Id">No</label>
                    </div>
                </div>
            </div>
            <div class="input-box">
                <label for="Checkbox_Other_@Model.Id">Other? Please explain</label>
                <input asp-for="Checkbox_Other" type="text" id="Checkbox_Other_@Model.Id" />
            </div>
        </div>
    </div>
</div>

步骤2:在主View中调用EditorFor

把原来的foreach循环替换成一行代码:

<form method="post" enctype="multipart/form-data" class="form-content-column" id="formFull">
    <div class="input-box">
        <label class="numbered" for="Name">Name<span class="span-mandatory">*</span></label>
        <input asp-for="Name" class="input-mandatory" type="text" id="Name" required />
        <span asp-validation-for="Name"></span>
        <input asp-for="Id" type="hidden" id="Id" required />
    </div>
    <div class="accordion" id="accordionExample">
        @* 使用EditorFor渲染整个集合 *@
        @Html.EditorFor(m => m.VenueItems)
    </div>
</form>

这种方式不仅代码更简洁,ASP.NET Core还会自动为每个集合项生成带索引的name属性,实现正确的Model绑定,同时方便后续维护单个项的表单逻辑。

为什么原来的foreach不行?

当你用foreach (var obj in Model.VenueItems)时,asp-for="@obj.IsEventHaveSustainableApproach"生成的name属性是obj.IsEventHaveSustainableApproach,而不是Model绑定器需要的VenueItems[0].IsEventHaveSustainableApproach格式。这种情况下,后端无法识别这些控件属于VenueItems集合,自然无法填充列表。

两种方法都不需要额外的JS处理,只要保证name格式正确,FormData提交就能正常绑定到ViewModel的List属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 22:52:29