我的模特里有一个List<Task>
。此列表包含2个任务(例如)
public List<Task> Tasks { get; set; }
public class Task {
public Task()
{
Title="";
Total= 0;
}
public string Title{ get; set; }
public int Total{ get; set; }
}
现在在我的剃刀视图中,我希望在我的模型的Tasks
中为每个List<Tasks>
渲染2个文本框。
我没有循环,只是放置直接文本框,如:
@Html.TextBoxFor(m => m.Tasks[0].Title, new { @maxlength = "50"})
@Html.TextBoxFor(m => m.Tasks[0].Total, new { @maxlength = "2"})
<br>
@Html.TextBoxFor(m => m.Tasks[1].Title, new { @maxlength = "50"})
@Html.TextBoxFor(m => m.Tasks[1].Total, new { @maxlength = "2"})
这样可以使表单正常,但单击提交按钮在FF中不会执行任何操作。但它在IE9中发布的很好。
查看源代码显示此html生成如下:
<input id="Tasks_0__Title" maxlength="50" name="Tasks[0].Title" type="text" value="" />
<input data-val="true" data-val-number="The field Total must be a number." data-val-required="The Total field is required." id="Tasks_0__Total" maxlength="2" name="Tasks[0].Total" type="text" value="" />
这个HTML看起来不正确。它有name="Tasks[0].Total"
似乎很奇怪。
我应该如何做到这一点,以便我可以在发布后从控制器中的List<>
访问文本框值?
谢谢
编辑:我只是保持一行进行测试。这是我在FF中看到的HTML。
<input id="Tasks_0__Title" type="text" value="" name="Tasks[0].Title" maxlength="50">
<input id="Tasks_0__Total" type="text" value="" name="Tasks[0].Total" maxlength="2" data-val-required="The Total field is required." data-val-number="The field Total must be a number." data-val="true">
单击提交按钮时不会发布此消息。
现在,如果我在FIREBUG中更改name="Tasks[0].Title" to name="Tasks_0__Title" and name="Tasks_0__Total"
,它就会发布。
如果我完全删除名称,它也会在FF中发布
你应该使用Tasks[0].Total
和Tasks[1].Total
而不是Items
:
@Html.TextBoxFor(m => m.Tasks[0].Title, new { @maxlength = "50"})
@Html.TextBoxFor(m => m.Tasks[0].Total, new { @maxlength = "2"})
<br/>
@Html.TextBoxFor(m => m.Tasks[1].Title, new { @maxlength = "50"})
@Html.TextBoxFor(m => m.Tasks[1].Total, new { @maxlength = "2"})
name="Tasks[0].Total"
并不奇怪。这正是输入应该如何命名,以便模型绑定器在POST操作中获取值。有关处理列表和词典时默认模型绑定程序使用的有线格式,请参阅this blog post。
这就是说我建议你使用编辑器模板=>而不是在你的视图中写下这5行代码替换它们:
@Html.EditorFor(x => x.Tasks)
然后在相应的编辑器模板(~/View/Shared/EditorTemplates/Task.cshtml
)中,它将自动为Tasks
集合中的每个元素呈现:
@model Task
@Html.TextBoxFor(m => m.Title, new { @maxlength = "50"})
@Html.TextBoxFor(m => m.Total, new { @maxlength = "2"})
<br/>
现在您可以让编辑器模板担心正确的命名约定等...
就你的POST动作而言:
[HttpPost]
public ActionResult Foo(MyViewModel model)
{
// model.Tasks should be correctly bound here
...
}
如果您想要多个元素与文本框。
for (int i = 0; i < Model.Students.Count; i++)
{
@Html.HiddenFor(modelIem => Model.Students[i].StudentId)
<tr>
<td>
@Html.DisplayFor(modelItem => Model.Students[i].Student.FirstNames)
</td>
<td>
@Html.DisplayFor(modelItem => Model.Students[i].Student.LastNames)
</td>
<td>
@Html.TextBoxFor(modelItem => Model.Students[i].Score, new { @type = "number" })
</td>
</tr> }
这是ViewModel
public class MyModel
{
public List<StudentGrade> Students { get; set; }
}
public class StudentGrade {
public ApplicationUser Student { get; set; }
[Range(1, 100)]
public int? Score { get; set; } = null;
public string Description { get; set; } = null;
public string StudentId { get; set; }
}