ASP.NET MVC提交表单后视图数据无法传递到控制器问题求助
问题原因
ASP.NET MVC 的模型绑定逻辑依赖表单提交字段的name属性,与Action方法接收参数的属性名一一对应,你当前表单生成的控件name与目标参数属性不匹配,因此绑定失败导致接收的screening变量为null。
具体错误点:
- 你写的
@Html.HiddenFor(s => screening.Id)生成的input的name属性为screening.Id,而Action的参数是Screening screening,模型绑定会去匹配screening参数下的screening.Id属性,显然不存在,无法正确绑定。 - 购票数量输入框使用
@Html.TextBoxFor(s => screening)绑定到了整个Screening对象,生成的name为screening,无法被正确转为有效数值,也会触发验证失败,打断模型绑定流程。
修复方案
1. 修改视图表单代码
调整循环内表单的控件写法,手动指定需要提交字段的name属性与目标参数属性一致:
@foreach (var screening in Model) { using (Html.BeginForm("Save", "Orders")) { @Html.ValidationSummary(true, "Please fix the following errors.") <tr> <td>@screening.Movie.Name</td> <td>@screening.Date.ToString("d MMM yyyy, HH:mm")</td> <td> <!-- 单独绑定购票数量,name可以自定义,和Action接收参数对应即可 --> <input type="number" name="TicketCount" value="1" min="1" max="@screening.AvailableSeats" required /> </td> <td>@screening.Price</td> <td><button type="submit" class="order-now-button">Order Now</button></td> </tr> <!-- 手动生成场次Id的隐藏域,name设为Id,和Screening类型的Id属性对应 --> <input type="hidden" name="Id" value="@screening.Id" /> <!-- 如果需要提交价格等其他字段也按同样方式加隐藏域 --> @Html.AntiForgeryToken() } }
2. 调整Action接收逻辑
可以根据业务需求选择两种接收方式:
方式1:单独接收参数(最简单)
[HttpPost] [ValidateAntiForgeryToken] public ActionResult Save(int Id, int TicketCount) { // 根据Id查询对应场次 var screening = _context.Screenings.FirstOrDefault(s => s.Id == Id); // 后续写订单生成、扣库存等业务逻辑 return RedirectToAction("", ""); }
方式2:用Screening类型接收
如果一定要用Screening作为参数的话,需要把所有非必填字段关闭验证,或者补充提交所有必填字段的隐藏域:
[HttpPost] [ValidateAntiForgeryToken] public ActionResult Save(Screening screening, int TicketCount) { // 业务逻辑 return RedirectToAction("", ""); }
3. 可选优化:新增专属订单提交ViewModel(更规范)
为了避免模型绑定混乱,建议单独建专门的提交参数类:
public class OrderSubmitViewModel { public int ScreeningId { get; set; } public int TicketCount { get; set; } public int Price { get; set; } }
表单里的隐藏域name对应这个ViewModel的属性名,Action直接接收该类型参数即可。
内容的提问来源于stack exchange,提问作者YarsCode
相关产品推荐
相关产品推荐

