【问题标题】:ASP.NET MVC 3 collecting/passing data from views with nested collections - data is lost in processASP.NET MVC 3 从具有嵌套集合的视图中收集/传递数据 - 数据在进程中丢失
【发布时间】:2011-11-04 14:32:10
【问题描述】:

我的模型是一个简单的父/子表示,如下所示

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

现在,我想创建一个页面,它允许我编辑/创建孩子 - 一次一个孩子就可以了。我想将父级传递到视图中,为 Child.Name 创建文本框,收集用户输入的任何内容,然后将其保存到数据库中。

因此,在我的控制器中的第一个 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] 中按“确定”时,父级会包含所有值,包括我新填充的值Child as null(实际上似乎只有Id是字段,我也不明白)。为什么?

我可以补充一点,如果我使用输入给 Child 的视图来执行此操作,那么它可以工作。我真的不能只通过一个孩子,因为我还需要跟踪/结转父母的身份证。这个我也不明白。

这是视图(首先是查看父级下的子级),这个运行正常:

@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 设置为传入的值。其他所有内容都设置为 null。包括父母和孩子的姓名。

这里是 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;
}

【问题讨论】:

  • 能否发布您的查看代码和AddChild

标签: c# asp.net-mvc-3


【解决方案1】:

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 是你的朋友 ;)。

编辑:在我最后变得很可爱之前,我想说一下 - 注意助手如何使用 for 循环呈现输入 name 属性(而不是foreach 循环)来了解 ModelBinder 正在寻找什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-23
    • 2014-06-11
    • 2018-12-08
    • 2011-11-08
    相关资源
    最近更新 更多