.NET 6表单List类型属性绑定失败及空引用异常问题求助
嘿,我来帮你梳理下问题所在,你遇到的两个核心问题:视图循环的空引用异常和模型绑定只拿到Email/Message,其实都是可以通过调整代码细节解决的,咱们一步步来:
一、先解决视图的空引用异常
你提到写@for (int i = 0; i < Model.Kids; i++)时出现空引用,原因有两个:
Model.Kids是List<KidsInformation>类型,不能直接和int比较,得用Model.Kids.Count;- 更关键的是,你的GET方法可能没有给视图传递初始化好的
PreInscription实例,导致Model本身为null,或者Model.Kids是空集合。
修复方案:
在InscriptionController里添加对应的GET方法,返回视图时初始化好模型:
public IActionResult PreInscription() { // 初始化模型,构造函数已创建空的Kids列表 var preInscriptionModel = new PreInscription(); // 默认显示1个孩子的输入项,主动添加实例 preInscriptionModel.Kids.Add(new KidsInformation()); return View(preInscriptionModel); }
然后视图里的循环改成:
@for (int i = 0; i < Model.Kids.Count; i++) { <div class="row" id="divAddChild_@i" style="margin-bottom: 5px;"> <div class="span6 form-group"> <input asp-for="Kids[i].KidsCount" type="number" class="form-control" placeholder="Combien pour cet age" /> </div> <div class="span6 form-group"> <input asp-for="Kids[i].KidAge" type="number" class="form-control " placeholder="Age" /> </div> </div> }
这样就不会有null引用问题,循环会根据Model.Kids的数量渲染对应输入项。
二、解决模型绑定只拿到Email和Message的问题
这个问题核心是手动覆盖了asp-for生成的name属性,同时AJAX提交格式和控制器的[FromForm]不匹配:
1. 移除手动设置的name属性
asp-for标签助手会自动生成符合模型绑定规则的name属性(比如FullName、Kids[0].KidsCount),但你手动给输入框加了name="name"、name="phoneNo"等自定义name,导致模型绑定无法识别这些字段,自然只能拿到未被覆盖name的字段(Email、Message)。
把这些手动name全部删掉:
<!-- 原代码:<input asp-for="FullName" type="text" name="name" ... /> --> <input asp-for="FullName" type="text" class="form-control" id="name" placeholder="Your Name" data-rule="minlen:4" data-msg="Please enter at least 4 chars" /> <!-- 原代码:<input asp-for="Phone" type="text" name="phoneNo" ... /> --> <input asp-for="Phone" type="text" class="form-control" id="phoneNo" placeholder="Phone No" data-rule="minlen:4" data-msg="Please enter at least 8 chars of subject" /> <!-- 孩子信息输入框同样删除手动name --> <input asp-for="Kids[i].KidsCount" type="number" class="form-control" placeholder="Combien pour cet age" /> <input asp-for="Kids[i].KidAge" type="number" class="form-control " placeholder="Age" />
2. 修复AJAX提交的格式问题
你现在的AJAX把表单序列化后转成JSON字符串,还设置了contentType: "application/json; charset=utf-8",但控制器用的是[FromForm],导致提交格式和接收方式不匹配,绑定失败。
修改AJAX代码,直接用表单序列化后的格式提交:
function runMethod(dataForm){ $.ajax({ url: '@Url.Action("PreInscription", "Inscription")', // 用Url.Action生成提交URL,而非Url.ActionLink type: 'POST', dataType: 'json', async: true, // 移除contentType,让jQuery自动使用表单提交默认格式 data: dataForm, success: function (response) { Swal.fire( 'Submitted!', 'Your request has been sent. Thank you!', 'success' ); }, error: function (request, status, error) { Swal.fire({ icon: 'error', title: 'Oops...', text: request.responseText, }) } }); }
三、额外建议:动态添加孩子输入项
如果想让用户点击按钮添加更多孩子输入框,可以参考这个思路:
- 给视图加一个"添加孩子"按钮;
- 点击按钮时,复制现有孩子输入框模板,修改
asp-for的索引值(比如从Kids[0]改成Kids[1]),再添加到DOM中; - 模型绑定依然能识别动态生成的
Kids[N]格式的name属性。
按照上面的步骤修改后,模型绑定应该就能正常接收所有字段,包括Kids列表里的内容了。
备注:内容来源于stack exchange,提问作者Adriel

