【问题标题】:MVC - Create object and related objects in one goMVC - 一次性创建对象和相关对象
【发布时间】:2014-10-11 11:15:27
【问题描述】:

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

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 的编辑器模板示例,但我的编辑器从未被调用。 我有 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; }
}

我这样做了:

  1. 为具有索引、创建、编辑功能的 Person 搭建了一个完整的控制器......
  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. 在 Create.cshtml 中添加了 @Html.EditorFor(m =&gt; m.Children)

问题:

  1. @Html.EditorFor(m =&gt; m.Children)如何可能与 当m.ChildrenPerson 的集合而不是单个时的编辑器模板 Person?
  2. 我想同时创建(而不是编辑)一个包含孩子的父亲。这意味着我没有要传递给 Create 视图的 ID。这怎么行?从 Shyju 的示例中,ID 已经预先创建?还是我只是误解了这个例子?

【问题讨论】:

  • 请发表您的看法

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


【解决方案1】:

您可以使用 EditorTemplates 来处理这个问题。这是一个工作示例。

所以我有一个视图模型来表示父子关系

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 操作方法中,我创建了一个视图模型对象并将父子数据加载到它。

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

的视图

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

@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 被传递给了这个动作方法。

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

【讨论】:

  • 非常详细的答案,但我还有一些其他问题。你介意分享你的项目吗?请参阅修改后的问题。
  • 我需要在编辑模板中的 ParentId 中添加一个HiddenFor 才能使这项工作:@Html.HiddenFor(s => s.ParentId)
  • 那么如何添加新条目?有没有办法为ICollection&lt;PersonVM&gt;编写模板?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多