ASP.NET MVC 3从嵌套集合的视图中收集/传递数据——数据在处理过程中丢失
本文关键字:数据 过程中 处理 MVC NET 嵌套 集合 视图 ASP | 更新日期: 2023-09-27 18:13:29
我的模型是一个简单的父/子表示,看起来像这样
public class Parent
{
public int Id { get; set; }
public string Name { get; set; }
public List<Child> Children { get; set; }
}
public class Child
{
public int Id { get; set; }
public string Name { get; set; }
}
现在,我想创建一个页面,它将允许我编辑/创建孩子-一次一个孩子就好了。我想把parent传递到视图中,为Child创建文本框。名称,收集用户输入的内容,然后将其保存到数据库中。
因此,在控制器的第一个CreateParent动作中,我创建了Parent(传入Id,因为我需要跟踪该Id[毕竟我需要知道我需要为哪个ParentId添加子元素]),如下所示:
[HttpGet]
public ActionResult CreateChild(int id)
{
var newParent = new Parent {
Id = id, Children = new List<Child> { new Child { Name = "ChildName" } } };
return View("~/Views/Home/CreateParent.cshtml", newParent);
}
页面加载,用户填写详细信息,按"确定"。然后运行这个动作:
[HttpPost]
public ActionResult CreateChild(Parent parent)
{
return View("~/Views/Home/ViewChildren.cshtml", AddChild(parent));
}
AddChild(parent)是一个私有函数,它处理一个给定父类的持久化子类,并返回一个包含更新过的子类的父模型。
这是我的问题/问题:呼叫之间数据丢失。当我在[HttpGet]中创建一个父时一切都很好,我可以看到在调试器中正确设置的值,但是当我在[HttpPost]中填写孩子数据并按"OK"时,父母带着所有值进来,包括我新填充的孩子为空(实际上只有Id字段似乎被结转,我也不明白)。为什么?
我可能会补充说,如果我这样做的视图,键入一个子,然后这工作。我真的不能只通过一个孩子,因为我还需要跟踪/结转父母的身份证。我也不明白。
下面是视图(第一个是查看父节点下的子节点),这个工作正常:
@model Parent
@{
ViewBag.Title = "AddChild";
}
<h2>Children for parent @Model.Name </h2>
<p>
@Html.ActionLink("Create New", "CreateChild", new {id = @Model.Id})
</p>
<table>
<tr>
<th>
Name
</th>
<tr>
@foreach (var child in @Model.Children) {
<tr>
<td>
@Html.DisplayFor(modelItem => child.Name)
</td>
<td>
@Html.ActionLink("Delete", "Delete", new { id=child.Id })
</td>
</tr>
}
</table>
下面是在父节点下创建子节点的视图:
@model Parent
@{
ViewBag.Title = "CreateChild";
}
<h2>Create new child for @Model.Name</h2>
@using (Html.BeginForm())
{
<table>
<tr>
<td>
Name:
</td>
</tr>
@foreach (var child in @Model.Children)
{
<tr>
<td>
@Html.EditorFor(modelItem => child.Name)
</td>
</tr>
}
</table>
<input id="submit" name="submit" type="submit" value="Save" />
}
因此,当我按下"保存"时,父级只会将Id设置为传入的值。其他的都被设为空。包括父母和孩子的名字。
这是AddChild方法:
private Parent AddChild(Parent parent)
{
var updatedParent = GetParent(int parent.Id);
updatedParent.Children.Add(parent.Children[0]); // this obviously fails as Children is NULL
return updatedParent;
}
Parent.Name
为NULL,因为您没有发布它。你需要加入@Html.TextBoxFor()
或@Html.HiddenFor()
。但是你不需要它,因为你正在加载持久化父元素。
对于孩子,尝试for
循环,而不是。
@for (var n = 0; n < Model.Children.Count; n++)
{
<tr>
<td>
@Html.EditorFor(modelItem => Model.Children[n].Name)
</td>
</tr>
}
这与ModelBinder
的工作方式有关。要知道,ModelBinder
是你的朋友;)。
编辑:在我得到所有可爱的结束之前,我想提到-注意助手如何呈现输入name
属性与for
循环(而不是foreach
循环),以了解ModelBinder
正在寻找什么。