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

Chu*_*584 5 asp.net-mvc entity-framework viewmodel asp.net-mvc-4

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

public class FatherViewModel {
  public Father father {get; set;} // has 1 property Name
  public List<Son> {get; set;} // has 1 property Name
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,如何在发布帖子时从视图中获取Sons列表?我已尝试为每个Son id使用HiddenFor,但无论如何,当返回到控制器时列表为空.

更新:

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

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; }
}
Run Code Online (Sandbox Code Playgroud)

我这样做了:

  1. 为索引,创建,编辑的人脚手架完整的控制器......
  2. 在Views-> Person中创建了EditorTemplates文件夹
  3. 创建Person.cshtml:

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

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

问题:

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

Shy*_*yju 9

您可以使用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; }
}
Run Code Online (Sandbox Code Playgroud)

在我的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);
}
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

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

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

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

@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"/>
}
Run Code Online (Sandbox Code Playgroud)

现在在控制器中有一个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);
}
Run Code Online (Sandbox Code Playgroud)

现在,如果在HttpPost操作方法中设置了断点,则可以看到子节点的Id被传递给此操作方法.

在此输入图像描述

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