我相信有一个名为 BeginCollectionItem HtmlHelper 的应用程序. It is 在这里简要讨论参考文献,并且基于史蒂夫·桑德森几年前写的博客文章.
问题在于,与表单集合的模型绑定与 MVC 中与标量输入的模型绑定并不完全相同。您的收藏需要一个索引器,正如这里所讨论的。如果它没有按预期绑定,请检查呈现的表单输入的名称属性,并将它们与后模型(操作参数)类中的属性名称和结构进行比较。
从表面上看,看起来更像这样的 HTML 输出应该会导致操作参数不为空:
<tr>
<td>HTTP 101</td>
<td>HTP-101</td>
<td>HTP-101</td>
<td><input type="checkbox" name="PossibleCourses[0].Selected" /></td>
<td><input type="text" name="PossibleCourses[0].Semester"></td>
<td><input type="text" name="PossibleCourses[0].Grade"></td>
</tr>
<tr>
<td>MVC 101</td>
<td>MVC-101</td>
<td>MVC-101</td>
<td><input type="checkbox" name="PossibleCourses[1].Selected" /></td>
<td><input type="text" name="PossibleCourses[1].Semester"></td>
<td><input type="text" name="PossibleCourses[1].Grade"></td>
</tr>
...等等,以下剃刀应输出:
@for (var i = 0; i <= Model.PossibleCourses.Count; i++)
{
var course = Model.PossibleCourses[i];
<tr>
<td>@course.BaseCourse.Name</td>
<td>@course.BaseCourse.CourseNumber</td>
<td>@course.BaseCourse.CourseNumber</td>
<td>@Html.CheckBox(string.Format("PossibleCourses[{0}].Selected", i),
course.Selected)</td>
<td>@Html.TextBox(string.Format("PossibleCourses[{0}].Semester", i),
course.Semester)</td>
<td>@Html.TextBox(string.Format("PossibleCourses[{0}].Grade", i),
course.Grade)</td>
</tr>
}
请注意表单输入元素的名称属性如何与可索引的名称相对应(List<Course>
) 操作参数模型中的属性,以及索引的 (Course
) 包含在集合内的属性名称。这是通过使输入名称属性与方法参数属性名称相匹配来帮助模型绑定器弄清楚如何使用数据填充操作参数类实例的一种方法。
您还可以使用 GUID(或任何与此相关的字符串)作为索引器,这就是 BeginItemCollection 内部所做的事情。以下内容还应该帮助模型绑定器能够填充操作参数,以便它不会作为 null 进入操作方法:
@foreach (var course in Model.PossibleCourses)
{
var indexer = Guid.NewGuid(); // or possibly course.CourseId
<tr>
<td>@course.BaseCourse.Name</td>
<td>@course.BaseCourse.CourseNumber</td>
<td>@course.BaseCourse.CourseNumber</td>
<td>@Html.Hidden("PossibleCourses.index", indexer)
@Html.CheckBox(string.Format("PossibleCourses[{0}].Selected", indexer),
course.Selected)</td>
<td>@Html.TextBox(string.Format("PossibleCourses[{0}].Semester", indexer),
course.Semester)</td>
<td>@Html.TextBox(string.Format("PossibleCourses[{0}].Grade", indexer),
course.Grade)</td>
</tr>
}
重要的是与操作参数类中的集合项对应的每组表单元素必须共享相同的索引器,并且该索引器必须与与操作参数类中的不同集合项对应的其他表单元素组不同。该解决方案的示例可以通过以下方式理解阅读这个问题及其答案.