ASP.NET Core MVC foreach循环生成的表单无法提交除首项外其余项输入值
问题根源
你当前的代码存在两个核心问题导致只有第一条数据能被正确识别:
- 所有抽奖项目的表单项
name属性完全重复,ASP.NET MVC的模型绑定机制无法区分重复名称对应的所属条目,默认只会取第一个匹配的字段值 - 你将所有项目行放在同一个表单内,点击任意行的提交按钮都会提交整个表单的所有字段,服务端无法正确解析多行数据
解决方案
根据你的使用场景(每行配有单独的提交按钮,应该是要单独提交每个项目的门票申请),推荐使用单项目独立表单方案,修改代码如下:
@model IEnumerable<HR.HolidayFamiliesApplication.Web.Models.RaffleList> @{ViewData["Title"] = "RaffleList";} <table class="table"> <tr> <th> @Html.DisplayNameFor(model => model.Raffle_ID) </th> <th> @Html.DisplayNameFor(model => model.Raffle_Item_Name) </th> <th> @Html.DisplayNameFor(model => model.Raffle_Item_Description) </th> <th></th> </tr> @foreach (var item in Model) { <!-- 把表单放到循环内部,每个行对应一个独立表单 --> @using (Html.BeginForm("InsertRecords", "Home", FormMethod.Post)) { <tr> <td> @Html.DisplayFor(modelItem => item.Raffle_ID) <input type="hidden" name="Raffle_ID" value="@item.Raffle_ID" /> </td> <td> @Html.DisplayFor(modelItem => item.Raffle_Item_Name) <input type="hidden" name="Raffle_Item_Name" value="@item.Raffle_Item_Name" /> </td> <td> @Html.DisplayFor(modelItem => item.Raffle_Item_Description) <input type="hidden" name="Raffle_Item_Description" value="@item.Raffle_Item_Description" /> </td> <td> <label>Number_of_Tickets</label> <input type="number" class="form-control" name="Number_of_Tickets" placeholder="Enter # Tickets" /> </td> <td> <input type="hidden" name="User_Name" value="@User.Identity.Name" /> </td> <td> <input class="btn btn-success" type="submit" value="Submit" /> </td> </tr> } } </table>
修改说明:
- 把表单声明移到
foreach循环内部,每个抽奖项目对应独立表单,提交时只会发送当前行的字段,不会和其他行冲突 - 修正了隐藏字段的value写法,直接取item的属性值,避免用
DisplayFor生成额外标签导致value值异常 - 去掉了重复的id属性,避免页面DOM id冲突
可选:批量提交方案
如果你需要一次提交所有项目的门票数量,可以改用for循环生成带索引的表单项,让MVC可以正确绑定为集合:
@model IList<HR.HolidayFamiliesApplication.Web.Models.RaffleList> @{ViewData["Title"] = "RaffleList";} @using (Html.BeginForm("InsertRecords", "Home", FormMethod.Post)) { <table class="table"> <tr> <th> @Html.DisplayNameFor(model => model[0].Raffle_ID) </th> <th> @Html.DisplayNameFor(model => model[0].Raffle_Item_Name) </th> <th> @Html.DisplayNameFor(model => model[0].Raffle_Item_Description) </th> <th></th> </tr> @for (int i = 0; i < Model.Count; i++) { <tr> <td> @Html.DisplayFor(modelItem => modelItem[i].Raffle_ID) <input type="hidden" name="[@i].Raffle_ID" value="@Model[i].Raffle_ID" /> </td> <td> @Html.DisplayFor(modelItem => modelItem[i].Raffle_Item_Name) <input type="hidden" name="[@i].Raffle_Item_Name" value="@Model[i].Raffle_Item_Name" /> </td> <td> @Html.DisplayFor(modelItem => modelItem[i].Raffle_Item_Description) <input type="hidden" name="[@i].Raffle_Item_Description" value="@Model[i].Raffle_Item_Description" /> </td> <td> <label>Number_of_Tickets</label> <input type="number" class="form-control" name="[@i].Number_of_Tickets" placeholder="Enter # Tickets" /> </td> </tr> } </table> <input type="hidden" name="User_Name" value="@User.Identity.Name" /> <input class="btn btn-success" type="submit" value="提交所有申请" /> }
对应控制器的InsertRecords方法参数改为List<RaffleList> model, string User_Name即可接收所有行的数据。
内容的提问来源于stack exchange,提问作者Michelle Ramos
相关产品推荐
相关产品推荐

