ASP.NET Core 8 MVC中视图提交IEnumerable<HourlyLimit>到控制器失败
问题原因
当你用foreach遍历IEnumerable<HourlyLimit>生成表单输入框时,asp-for="@item.ID"会生成name="item.ID"这类属性,ASP.NET Core的模型绑定器无法识别这种无索引的命名格式,因此无法将提交的表单数据绑定到IEnumerable<HourlyLimit>参数,导致接收的集合count为0。
正确解决方案
方法1:改用IList与for循环
1. 调整Get方法返回类型
将返回的模型从IEnumerable<HourlyLimit>改为IList<HourlyLimit>,支持索引访问:
IList<HourlyLimit> hourlyLimits = await _db.HourlyLimits .OrderBy(h => h.Hour) .ToListAsync(); return View(hourlyLimits);
2. 修改视图循环逻辑
视图模型改为IList<HourlyLimit>,用for循环遍历,asp-for会自动生成带索引的name属性:
@model IList<HourlyLimit> <html> <head><title></title></head> <body> <form method="post" action="~/Admin/HourlyLimits/Set"> @for (int i = 0; i < Model.Count; i++) { <input asp-for="@Model[i].ID" hidden /> <input asp-for="@Model[i].Date" hidden /> <input asp-for="@Model[i].Hour" hidden /> <input asp-for="@Model[i].Capacity" type="number"> } <button type="submit">提交</button> </form> </body> </html>
生成的input会带有[0].ID、[1].Capacity这类带索引的name属性,模型绑定器能正确识别并绑定到集合。
方法2:使用EditorTemplate(更优雅的实现)
1. 创建EditorTemplate
在Views/Shared/EditorTemplates目录下新建HourlyLimit.cshtml视图:
@model HourlyLimit <input asp-for="ID" hidden /> <input asp-for="Date" hidden /> <input asp-for="Hour" hidden /> <input asp-for="Capacity" type="number">
2. 简化主视图代码
主视图直接调用Html.EditorFor,它会自动处理集合的索引命名,无需修改Get方法的返回类型:
@model IEnumerable<HourlyLimit> <html> <head><title></title></head> <body> <form method="post" action="~/Admin/HourlyLimits/Set"> @Html.EditorFor(m => m) <button type="submit">提交</button> </form> </body> </html>
额外注意事项
- 移除
enctype="multipart/form-data",该属性仅用于文件上传场景,会改变表单编码方式,干扰普通模型绑定。 - 确保
HourlyLimit类的属性为公共访问级别,且存在无参构造函数(默认自动生成,除非自定义了带参构造函数),否则模型绑定器无法实例化对象。
内容的提问来源于stack exchange,提问作者Sina Abbaszadeh
相关产品推荐
相关产品推荐

