ASP.NET MVC使用Html.BeginForm提交对象列表报ArgumentNullException
异常根因
抛出System.ArgumentNullException是因为提交表单时后端接收的List<Student>参数为null,后续直接调用Count、索引取值触发空异常,具体问题点如下:
- 表单字段命名和控制器参数名不匹配:JS动态生成输入框时用的前缀是
studentModels[索引],但控制器接收列表的参数名是s,默认模型绑定器无法识别对应字段,直接传null。 - 动态生成的年龄输入框属性错误:给年龄输入框写的是
Age="xxx",表单提交依赖name属性识别字段,缺少name属性的输入框值不会被提交到后端。 - 代码笔误:控制器里写的
ViewBad.Value是拼写错误,正确写法是ViewBag.Value;视图的tbody标签未闭合,DOM结构异常。 - 元素id重复:循环生成的输入框都用了固定id
Name/Age,id是页面唯一标识,重复会导致JS永远只能取到第一个输入框的值,无法获取当前填写内容。 - 初始请求未传模型实例:GET加载视图时如果没有给视图传递初始化的
List<Student>对象,视图里直接调用Model.Count()也会触发空异常。 - 初始输入行的name格式不匹配:用
Html.TextBoxFor生成的初始输入框name没有和动态字段保持统一前缀,提交时第一行数据无法被绑定。
修复方案
1. 修正控制器代码
统一参数名和表单前缀,增加空值校验,修正拼写错误,补全GET请求的模型传值:
// GET请求加载页面 public ActionResult Index() { // 传递初始化空列表,避免视图端Model为null return View(new List<Student>()); } [HttpPost] // 参数名和表单字段前缀保持一致,命名为studentModels public ActionResult Form(List<Student> studentModels) { // 增加空值校验,避免绑定失败直接抛异常 if (studentModels == null || studentModels.Count == 0) { ViewBag.Items = 0; ViewBag.Value = 0; return View("Index", new List<Student>()); } ViewBag.Items = studentModels.Count; // 修正ViewBad的拼写错误 ViewBag.Value = studentModels[0].Age; return View("Index", studentModels); }
2. 修正视图代码
修复DOM结构、重复id、字段name匹配问题:
@model List<MVCModel.Models.Student> <b>Items</b> @ViewBag.Items <br /> <b>Value</b> @ViewBag.Value <br /> @using (Html.BeginForm("Form", "Home", FormMethod.Post)) { <table> <tbody id="GenaratorList"> <tr> <td>Enter Name: </td> <!-- 初始输入框name和动态生成规则保持一致,用类名给JS取值,避免重复id --> <td><input type="text" class="input-name form-control" name="studentModels[0].Name"></td> <td>Enter Age: </td> <td><input type="text" class="input-age form-control" name="studentModels[0].Age"></td> <td><input type="button" value="Add" onclick="addGenarator()" /></td> </tr> <!-- 补全tbody闭合标签 --> </tbody> </table> <input type="submit" value="Submit Form"/> } <script> // 初始索引从1开始,0已经被页面固定的第一行输入占用 let count = 1; function addGenarator() { // 通过类名获取输入值,避免重复id导致取值错误 const nameVal = $('.input-name').val(); const ageVal = $('.input-age').val(); const fieldPrefix = "studentModels[" + count + "]"; // 年龄输入框必须设置name属性,删除错误的Age属性 $('#GenaratorList').append('<tr><td><input name="' + fieldPrefix + '.Name" type="text" class="form-control" readonly value="' + nameVal + '"></td><td><input name="' + fieldPrefix + '.Age" type="text" class="form-control" readonly value="' + ageVal + '"></td></tr>'); // 清空输入框 $('.input-name,.input-age').val(''); count++; } </script>
修复后所有提交的字段名都是studentModels[索引].属性名的连续索引格式,和控制器参数名完全匹配,模型绑定器可以正确解析成List<Student>实例,不会再出现null异常。
内容的提问来源于stack exchange,提问作者dap
相关产品推荐
相关产品推荐

