MVC - 一次创建对象和相关对象

时间:2014-08-18 13:53:51

标签: asp.net-mvc entity-framework asp.net-mvc-4 viewmodel

我想在同一视图中创建一个包含子/相关对象的父对象。 一个例子是:创建一个父亲(带有一些名字)以及他所有的儿子(带有他们的名字)。我创建了一个视图模型:

public class FatherViewModel {
  public Father father {get; set;} // has 1 property Name
  public List<Son> {get; set;} // has 1 property Name
}

我的问题是,如何在发布帖子时从视图中获取Sons列表? 我已经尝试为每个Son id使用HiddenFor,但不管怎样,返回控制器时列表都是空的。

更新

我尝试了下面描述的Shyju的编辑模板示例,但我的编辑器从未被调用过。 我有一个对象:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int? FatherId { get; set; }
    public virtual ICollection<Person> Children { get; set; }
}

我这样做了:

  1. 为具有索引,创建,编辑...的人提供了一个完整的控制器;
  2. 在Views-&gt; Person
  3. 中创建了EditorTemplates文件夹
  4. 创建Person.cshtml:

    @model TestEditorTemplate.Models.Person <div> <h4>Child</h4> @Html.TextBoxFor(s => s.Name) @Html.HiddenFor(s => s.Id) </div>

  5. @Html.EditorFor(m => m.Children)添加到Create.cshtml

  6. 问题:

    1. @Html.EditorFor(m => m.Children)如何使用。m.Children PersonPerson的集合而不是单个集合时的编辑器模板 {{1}}?
    2. 我想同时创建(不编辑)包括孩子在内的父亲。这意味着我没有ID传递给Create视图开始。这怎么办?从Shyju的例子来看,Ids已经预先创建了?或者我只是误解了这个例子?

1 个答案:

答案 0 :(得分:8)

您可以使用 EditorTemplates 来处理此问题。这是一个工作样本。

所以我有一个用于表示父子关系的viewmodel

public class PersonVM
{
    public int Id { set; get; }
    public string Name { set; get; }
    public int? ParentId { set; get; }
    public List<PersonVM> Childs { set; get; }
}

在我的GET操作方法中,我创建了一个视图模型的对象,并将Father -childs数据加载到它。

public ActionResult EditorTmp(int id = 1)
{
    //Hard coded for demo, you may replace with actual DB values
    var person = new PersonVM {Id = 1, Name = "Mike"};
    person.Childs = new List<PersonVM>
    {
        new PersonVM {Id = 2, Name = "Scott", ParentId = 11},
        new PersonVM {Id = 2, Name = "Gavin", ParentId = 12}
    };
    return View(person);
}

现在我将创建一个EditorTemplate。为此,请转到Views文件夹,并在与控制器同名的目录下创建名为 EditorTemplates 的目录,并添加名为PersonVM.cshtml的视图

enter image description here

现在,转到此视图并添加以下代码。

@model ReplaceWithYourNameSpaceNameHere.PersonVM
<div>
    <h4>Childs </h4>
    @Html.TextBoxFor(s => s.Name)
    @Html.HiddenFor(s => s.Id)
</div>

现在让我们回到主视图。我们需要将此视图强烈输入到原始PersonVM。我们将在此视图中使用EditorFor html辅助方法来调用我们的编辑器模板

@model ReplaceWithYourNameSpaceNameHere.PersonVM
@using (Html.BeginForm())
{
    <div>
        @Html.TextBoxFor(s => s.Name)
        @Html.HiddenFor(s => s.Id)
    </div>
    @Html.EditorFor(s=>s.Childs)
   <input type="submit"/>
}

现在控制器中有一个HttpPost方法来处理表单发布

[HttpPost]
public ActionResult EditorTmp(PersonVM model)
{
    int fatherId = model.Id;
    foreach (var person in model.Childs)
    {
        var id=person.Id;
        var name = person.Name;
    }
    // to do  : Save ,then Redirect (PRG pattern)
    return View(model);
}

现在,如果你在HttpPost动作方法中设置一个断点,你可以看到子动画的Id被传递给这个动作方法。

enter image description here

要记住的一件重要事情是,您的编辑器模板视图的名称应与您绑定它的类型相同。