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;
}

ASP.NET MVC 3从嵌套集合的视图中收集/传递数据——数据在处理过程中丢失

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正在寻找什么。