ASP.NET Core MVC中Razor模态框提交集合为空的解决方法
核心原因
ASP.NET Core MVC的模型绑定要求集合元素的表单字段遵循带索引的命名规则(如LocationServicePrices[0].PricePerUnit),但你用foreach循环生成的输入框name属性仅为PricePerUnit,无法被识别为集合的一部分,导致后端接收时LocationServicePrices为null。
具体修复步骤
1. 修改视图中的集合遍历方式
将foreach替换为for循环(先把ICollection转为List以支持索引访问),确保生成符合绑定规则的字段名称:
@* 先将ICollection转为List,方便通过索引访问元素 *@ @{ var priceList = Model.LocationServicePrices.ToList(); } @for (int i = 0; i < priceList.Count; i++) { <div class="form-group"> <label>@priceList[i].PricingTierName</label> @* 编辑场景下必须添加隐藏字段传递Id,确保后端能匹配对应元素 *@ <input type="hidden" asp-for="@priceList[i].Id" /> <input class="form-control" type="text" asp-for="@priceList[i].PricePerUnit" data-rule-number="true" data-rule-min="0" data-rule-max="@AppConsts.MaxDecimalDatabaseLength"> </div> }
2. 验证表单字段格式
修改后查看页面源码,输入框的name属性应呈现为LocationServicePrices[0].PricePerUnit、LocationServicePrices[1].PricePerUnit这类格式,这是模型绑定识别集合的关键。
3. 确认模型兼容性
你的LocationServiceEditDto中LocationServicePrices属性为ICollection<LocationServicePriceDto>,ASP.NET Core MVC可自动将符合格式的表单数据绑定到该集合,无需修改模型(若需更直观的索引支持,也可改为List<LocationServicePriceDto>,不影响绑定效果)。
4. 序列化逻辑验证
你的serializeFormToObject方法使用的serializeJSON工具,会自动将LocationServicePrices[0].PricePerUnit这类字段序列化为JSON数组:
{ "Id": "xxx", "ServiceId": "xxx", // ...其他字段 "LocationServicePrices": [ { "Id": "1", "PricePerUnit": "150" }, { "Id": "2", "PricePerUnit": "200" } ] }
该格式可被后端正确解析为ICollection<LocationServicePriceDto>类型。
额外注意事项
- 新增场景可省略
Id隐藏字段,编辑场景必须传递,否则后端无法识别需更新的具体元素。 - 确保
LocationServicePriceDto包含Id、PricePerUnit等必要属性,且属性名称与表单字段一致(大小写不敏感,但建议保持统一)。
内容的提问来源于stack exchange,提问作者Eugene Sukh

