ASP.NET Core 8 Razor Pages中List<T>绑定HTML表格POST元素为空问题
ASP.NET Core 8.0 Razor Pages 集合绑定后元素全为null的问题
问题场景
基于ASP.NET Core 8.0 Razor Pages开发,页面包含一个可修改服务价格的表格。已定义模型类ServProdModel,并在PageModel中声明绑定属性集合:
[BindProperty] public List<ServProdModel>? Servs { get; set; }
GET请求时数据绑定正常,但POST提交后出现异常:Request.Form中能看到完整的集合数据,Servs.Count也正确对应5项服务,但列表内所有元素均为null,触发System.NullReferenceException: Object reference not set to an instance of an object。
当前实现代码
PageModel绑定属性
[BindProperty] public List<ServProdModel>? Servs { get; set; }
页面表格绑定(显式索引方式)
@foreach (var itm in Model.Servs) { <tr> <td class="visually-hidden"> <input type="hidden" name='Servs.Index' value='@itm.ServID' /> <input type="hidden" name='Servs[@itm.ServID].ServID' value='@itm.ServID' /> </td> <td> <input type="text" name='Servs[@itm.ServID].Price' value='@itm.Price' /> </td> <!-- 其他列省略 --> </tr> }
已尝试操作
- 改用
for循环实现绑定,问题依旧。 - 尝试顺序索引方式:
- 取消注释
int i = 0;和i++; - 注释
<input type="hidden" name='Servs.Index' value='@itm.ServID' /> - 将
Servs[@itm.ServID]替换为Servs[@i]
但Request.Form中能看到集合数据,Servs元素仍为null。
- 取消注释
可复现代码
已提供最小可复现代码:
- TestPg.cshtml(保持上述表格代码)
- TestPg.cshtml.cs(保持上述绑定属性代码)
解决方法
核心原因
ServProdModel缺少无参构造函数,绑定系统无法自动实例化对象;- 显式索引(如
ServID这类非连续数值)的绑定格式不符合ASP.NET Core模型绑定的预期,导致无法正确创建集合元素实例。
修复步骤
给
ServProdModel添加无参构造函数
模型类必须包含无参构造函数,否则绑定系统无法生成实例:public class ServProdModel { public int ServID { get; set; } public decimal Price { get; set; } // 必须添加无参构造函数 public ServProdModel() {} // 带参构造函数可保留,但无参构造不能少 public ServProdModel(int servID, decimal price) { ServID = servID; Price = price; } }改用顺序索引的
for循环+标签助手
这是Razor Pages中集合绑定最稳定的方式,asp-for标签助手会自动生成正确的name属性,避免手动拼接出错:@for (int i = 0; i < Model.Servs.Count; i++) { <tr> <td class="visually-hidden"> <input type="hidden" asp-for="Servs[i].ServID" /> </td> <td> <input type="text" asp-for="Servs[i].Price" /> </td> <!-- 其他列 --> </tr> }POST处理程序中初始化集合(可选)
若POST时集合未被正确初始化,可在处理方法开头手动初始化:public IActionResult OnPost() { Servs ??= new List<ServProdModel>(); // 检查模型状态,排查绑定错误 if (!ModelState.IsValid) { // 输出ModelState错误,定位具体问题 foreach (var error in ModelState.Values.SelectMany(v => v.Errors)) { Console.WriteLine(error.ErrorMessage); } return Page(); } // 后续保存数据等逻辑 return RedirectToPage(); }
内容的提问来源于stack exchange,提问作者NP3
相关产品推荐
相关产品推荐

