C# ASP.NET MVC 提交表单时List<T>模型绑定接收为空如何解决
问题根因
- 表单字段前缀与Action接收参数不匹配:视图基于
FormAddOrderItemModel生成的表单字段name统一带有ContentsList[索引].前缀,而Action接收的参数是无对应前缀的List<FormContents>,模型绑定器无法匹配字段与参数属性。 - 无法直接绑定复杂对象到隐藏字段:
@Html.HiddenFor(m => m.ContentsList[i].OrderItem, item)无法将整个OrderItem复杂对象序列化后传递,默认模型绑定器不支持该操作。 ContentsList未提前初始化:视图循环依赖Model.OrderItems.Count,如果返回视图时未初始化对应长度的ContentsList,会出现索引越界,也无法生成正确的表单字段。
解决方案
步骤1:提前初始化视图模型
在返回该分部视图的GET逻辑中,同步初始化ContentsList,保证长度与OrderItems一致:
var model = new FormAddOrderItemModel { OrderItems = // 你的OrderItems查询结果 ContentsList = OrderItems.Select(item => new FormContents { OrderItem = item, Quantity = 0 }).ToList() }; return PartialView(model);
步骤2:修正视图隐藏字段
仅传递OrderItem的主键字段(如Id),不要传递整个对象,避免数据篡改和绑定失败:
@using FormAddOrderItemModel = Restaurant.Models.Order.Form.FormAddOrderItemModel @model FormAddOrderItemModel; @using (Html.BeginForm("Form_AddOrderItems", "Order", FormMethod.Post)) { for (var i = 0; i < Model.ContentsList.Count; i++) { var item = Model.ContentsList[i].OrderItem; <div> @Html.Label(item.Name) @* 仅存OrderItem主键 *@ @Html.HiddenFor(m => m.ContentsList[i].OrderItem.Id) @Html.LabelFor(m => m.ContentsList[i].Quantity) @Html.TextBoxFor(m => m.ContentsList[i].Quantity) </div> } <input class="btn btn-primary" type="submit" value="Submit"> }
步骤3:修正控制器Action参数
二选一即可:
方案A:直接接收完整视图模型(推荐,后续扩展更方便)
[HttpPost] public IActionResult Form_AddOrderItems(FormAddOrderItemModel model) { var response = model.ContentsList; // 后续根据OrderItem.Id查询完整实体,执行业务逻辑 return View("ManageOrder", _orderService.PrepareManageOrderViewModel(12)); }
方案B:为现有参数加绑定前缀
[HttpPost] public IActionResult Form_AddOrderItems([Bind(Prefix = "ContentsList")] List<FormContents> response) { // response可正常获取绑定的集合数据 return View("ManageOrder", _orderService.PrepareManageOrderViewModel(12)); }
内容的提问来源于stack exchange,提问作者shinyshark
相关产品推荐
相关产品推荐

