ASP.NET Core分部页面表单提交后控制器无法接收数据问题
问题原因与解决方案
核心问题是表单字段命名不符合ASP.NET Core模型绑定的列表格式要求,导致控制器无法将提交的零散字段组装成List<RequestConsultProdData>。
具体问题分析
你当前的表单通过foreach循环生成的input字段,其name属性类似prod.ConsultorProdutos.ConsultorProdutoId,既没有列表参数名前缀,也没有索引标识。模型绑定系统无法识别这些字段属于同一个列表的不同项,因此接收的requestConsultProdDatas为空。
解决方案:规范表单字段命名
有两种常用方式实现正确的模型绑定:
方法1:手动指定name属性(适配现有foreach循环)
在foreach循环中为每个input字段添加带索引的name属性,与控制器参数名requestConsultProdDatas对应:
@using MysticalServices.Models.UtilClasses; @model IEnumerable<MysticalServices.Models.UtilClasses.ConsultorProdutoCompleto> <div id="productContainer"> List of products: <form asp-action="SaveProdConsult"> @foreach(var item in Model.Select((prod, index) => new { prod, index })) { var prod = item.prod; var i = item.index; <div class="product-card"> <!-- 手动指定name,对应控制器的列表参数+索引 --> <input type="hidden" name="requestConsultProdDatas[@i].ConsultorProdutoId" value="@prod.ConsultorProdutos.ConsultorProdutoId" class="cPInputHidden" /> <div class="product-title"> @prod.Produtos.Nome </div> <div class="prod-description"> @prod.Produtos.Descricao </div> <div class="toggler-container" id="toggler_container_prod_@prod.ConsultorProdutos.ConsultorProdutoId"> <div class="toggler@(prod.ConsultorProdutos.Available ? " positive" : "")" id="toggler_prod_@prod.ConsultorProdutos.ConsultorProdutoId" data-is-available="@prod.ConsultorProdutos.Available.ToString().ToLower()" onclick="updateProdToggle(@prod.ConsultorProdutos.ConsultorProdutoId)"> <div class="toggle-circle" id="toggle_circle_prod_@prod.ConsultorProdutos.ConsultorProdutoId" style="@(prod.ConsultorProdutos.Available ? "transform : translate(50px)" : "")"></div> </div> <div class="status" id="status_prod_@prod.ConsultorProdutos.ConsultorProdutoId"> @if(prod.ConsultorProdutos.Available) { <input type="hidden" name="requestConsultProdDatas[@i].Available" value="1" id="available_@prod.ConsultorProdutos.ConsultorProdutoId" /> <span>Online</span> } else { <input type="hidden" name="requestConsultProdDatas[@i].Available" value="0" id="available_@prod.ConsultorProdutos.ConsultorProdutoId" /> <span>Offline</span> } </div> </div> </div> } <button type="submit">Guardar</button> </form> </div>
方法2:改用for循环+asp-for(更贴合ASP.NET Core约定)
将模型改为IList<ConsultorProdutoCompleto>(或在视图中转换),使用for循环生成带索引的字段:
- 修改视图模型声明:
@model IList<MysticalServices.Models.UtilClasses.ConsultorProdutoCompleto>
- 替换foreach为for循环:
@for(int i = 0; i < Model.Count; i++) { <div class="product-card"> <!-- asp-for自动生成带索引的name --> <input asp-for="@Model[i].ConsultorProdutos.ConsultorProdutoId" class="cPInputHidden" type="hidden" /> <div class="product-title"> @Model[i].Produtos.Nome </div> <div class="prod-description"> @Model[i].Produtos.Descricao </div> <div class="toggler-container" id="toggler_container_prod_@Model[i].ConsultorProdutos.ConsultorProdutoId"> <div class="toggler@(Model[i].ConsultorProdutos.Available ? " positive" : "")" id="toggler_prod_@Model[i].ConsultorProdutos.ConsultorProdutoId" data-is-available="@Model[i].ConsultorProdutos.Available.ToString().ToLower()" onclick="updateProdToggle(@Model[i].ConsultorProdutos.ConsultorProdutoId)"> <div class="toggle-circle" id="toggle_circle_prod_@Model[i].ConsultorProdutos.ConsultorProdutoId" style="@(Model[i].ConsultorProdutos.Available ? "transform : translate(50px)" : "")"></div> </div> <div class="status" id="status_prod_@Model[i].ConsultorProdutos.ConsultorProdutoId"> @if(Model[i].ConsultorProdutos.Available) { <input asp-for="@Model[i].ConsultorProdutos.Available" id="available_@Model[i].ConsultorProdutos.ConsultorProdutoId" type="hidden" value="1" /> <span>Online</span> } else { <input asp-for="@Model[i].ConsultorProdutos.Available" id="available_@Model[i].ConsultorProdutos.ConsultorProdutoId" type="hidden" value="0" /> <span>Offline</span> } </div> </div> </div> }
此时控制器需要调整参数类型为List<ConsultorProdutoCompleto>,或者保持原RequestConsultProdData但确保字段名与生成的name属性对应(比如将RequestConsultProdData的字段改为ConsultorProdutoId和Available,与表单字段一致)。
验证
修改后提交表单,控制器的requestConsultProdDatas列表将正确接收每个产品的ID和状态值,即可进行后续数据库更新操作。
内容的提问来源于stack exchange,提问作者Phil
相关产品推荐
相关产品推荐

