我正在使用编辑器模板来显示与表单关联的项目列表,并且我允许用户在不需要时删除行 但是,当用户在删除 POST 操作上的任何行后提交表单时,我得到的集合为 null,如果用户没有删除任何项目,我会在 POST 操作中获得带有修改值的完整集合。 这是我尝试使用模型 Controller 和 View 的代码
型号
public class Student
{
public string StudName { get; set; }
public int StudId { get; set; }
public List<Assignment> Assignments { get; set; }
}
public class Assignment
{
public int Id{get;set;}
public string Name{get;set;}
public int Amount{get;set;}
public string Remarks{get;set;}
}
Controller 操作
public ActionResult Assign(int Id)
{
Student model = new Student { StudId = Id, StudName = "Name +" + Id };
List<Assignment> _assignments = new List<Assignment>();
for(int j=0;j<3;j++)
{
Assignment itm = new Assignment { Id = j, Name = "Assign " + j, Remarks = "Remarks " + j, Amount = j * 33 };
_assignments.Add(itm);
}
model.Assignments = _assignments;
return View(model);
}
[HttpPost]
public ActionResult Assign(int Id,Student model)
{
return Content("rxvd "+model.Assignments.Count);
//count is correct if not removing anything from Assign page
//If i remove any items from assign page then count is null
}
指定 View
@model OpenXMLMvc3.Controllers.Student
@{
ViewBag.Title = "Assign";
}
<h2>Assign</h2>
<script type="text/javascript">
$(function () {
//call from Editor template
$("a.deleteRow").live("click", function () {
$(this).parents("tr.editorRow:first").remove();
return false;
});
});
</script>
@using (Html.BeginForm())
{
@Html.ValidationSummary(true)
<div class="col-md-6">
<div class="editor-label">
@Html.LabelFor(model => model.StudName)
@Html.EditorFor(model => model.StudName)
@Html.ValidationMessageFor(model => model.StudName)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.StudId)
@Html.EditorFor(model => model.StudId)
@Html.ValidationMessageFor(model => model.StudId)
</div>
</div>
<div class="col-md-6">
<table id="container">
@for (int j = 0; j < Model.Assignments.Count; j++)
{
//using editor template to list the assignments
@Html.EditorFor(model => Model.Assignments[j])
}
@*This will [using foreach instead of for ] result a NULL at form submission even without editing or removing any rows
@foreach (OpenXMLMvc3.Controllers.Assignment assign in Model.Assignments)
{
@Html.EditorFor(model => assign)
}*@
</table>
</div>
<p>
<input type="submit" value="Create" />
</p>
}
编辑器模板 View
@model OpenXMLMvc3.Controllers.Assignment
<tr class="editorRow">
<td>
@Html.HiddenFor(model => Model.Id, new {@class="iHidden" })
sa
</td>
<td>
@Html.EditorFor(model => Model.Name)
</td>
<td>
@Html.EditorFor(model => Model.Amount)
</td>
<td>
@Html.EditorFor(model => Model.Remarks)
</td>
<td>
<a href="#" class="deleteRow">delete</a>
</td>
</tr>
那么我如何允许用户通过 MVC3 中的 EditorTemplates 从集合中删除项目
最佳答案
默认情况下 DefaultModelBinder
只会绑定(bind)从零开始且连续的集合。如果删除第一个项目(索引 = 0),则不会绑定(bind)任何项目。您需要在 View 中包含特殊的隐藏输入,DefaultModelBinder
用于匹配非连续索引器。
不幸的是,您将无法使用 EditorTemplate
在这种情况下,您需要使用 for
在主视图内循环(但作为替代方案,您可以使用 BeginCollectionItem 帮助器作为使用 for
循环的选项)。
将主视图更改为
<table id="container">
@for (int j = 0; j < Model.Assignments.Count; j++)
{
<tr class="editorRow">
<td>
@Html.HiddenFor(m => m.Assignments[j].Id, new {@class="iHidden" })
sa
<input type="hidden" name="Assignments.Index" value="@j" /> // add this
</td>
<td>@Html.EditorFor(m => m.Assignments[j].Name)</td>
<td>@Html.EditorFor(m => m.Assignments[j].Amount)</td>
<td>@Html.EditorFor(m => m.Assignments[j].Remarks)</td>
<td><a href="#" class="deleteRow">delete</a></td>
</tr>
}
</table>
旁注:EditorFor()
接受 IEnumerable<T>
所以你之前尝试的正确用法应该是
<table id="container">
@Html.EditorFor(model => Model.Assignments)
</table>
即不在循环中 - EditorFor()
该方法足够智能,可以根据模板为集合中的每个项目生成正确的 html
此外,我建议不要使用 model => Model.XXX
(大写“M”)。在某些情况下它可能会抛出异常(在任何情况下,仅使用 m => m.XXX
会更简单)
另请注意,上面提到的 BeginCollectionItem 帮助程序只是自动添加此隐藏输入,并将基于零的索引器更改为 Guid
所以生成的html是
<input type="hidden" name="Assignments[aaaef973-d8ce-4c92-95b4-3635bb2d42d5].ID" .... />
<input type="hidden" name="Assignments.Index" value="aaaef973-d8ce-4c92-95b4-3635bb2d42d5" />
但是,如果您还动态地将新项目添加到 View 中的集合中,那么它就会发挥作用
关于c# - 如果从 View 中删除 Editortemplates 项目,MVC 表单提交将返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31601916/