asp.net-mvc MVC - 一次性创建对象和相关对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25365043/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
MVC - Create object and related objects in one go
提问by Chuckels5584
I want to create a parent object with child/related objects in the same view. An example would be: create one Father (with some name) along with all his sons (with their names). I have created a view model:
我想在同一个视图中创建一个带有子/相关对象的父对象。一个例子是:创造一个父亲(有名字)和他所有的儿子(有他们的名字)。我创建了一个视图模型:
public class FatherViewModel {
public Father father {get; set;} // has 1 property Name
public List<Son> {get; set;} // has 1 property Name
}
My question is, how do I get the list of Sons back from the view when the post is performed? I have tried using HiddenFor for each Son id, but no matter what, the list is empty when returned to the controller.
我的问题是,如何在执行帖子时从视图中取回儿子的列表?我曾尝试为每个 Son id 使用 HiddenFor,但无论如何,当返回到控制器时列表为空。
UPDATE:
更新:
I tried the Editor Template example by Shyju described below, but my editor is never called. I have 1 object:
我尝试了下面描述的 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; }
}
I did this:
我这样做了:
- Scaffolded a full controller for Person with index, create, edit...
- Created EditorTemplates folder in Views->Person
Created Person.cshtml:
@model TestEditorTemplate.Models.Person <div> <h4>Child</h4> @Html.TextBoxFor(s => s.Name) @Html.HiddenFor(s => s.Id) </div>Added
@Html.EditorFor(m => m.Children)to Create.cshtml
- 为具有索引、创建、编辑...
- 在 Views->Person 中创建 EditorTemplates 文件夹
创建的 Person.cshtml:
@model TestEditorTemplate.Models.Person <div> <h4>Child</h4> @Html.TextBoxFor(s => s.Name) @Html.HiddenFor(s => s.Id) </div>添加
@Html.EditorFor(m => m.Children)到 Create.cshtml
Questions:
问题:
- How can
@Html.EditorFor(m => m.Children)possibly work with the editor template whenm.Childrenis a collection ofPersonand not a singlePerson? - I want to create (not edit) a father including children at the same time. That means that I have no Ids to pass to the Create view to start with. How can this work? From the example by Shyju, the Ids are already created beforehand?? Or did I just misunderstand the example?
@Html.EditorFor(m => m.Children)当m.Children是一个集合Person而不是单个 时,怎么可能使用编辑器模板Person?- 我想同时创建(而不是编辑)包括孩子在内的父亲。这意味着我没有要传递给 Create 视图的 ID。这怎么工作?从 Shyju 的例子来看,Ids 已经预先创建了??或者我只是误解了这个例子?
回答by Shyju
You can use EditorTemplatesto handle this. Here is a working sample.
您可以使用EditorTemplates来处理此问题。这是一个工作示例。
So i have a viewmodel to represent the father-child relationship
所以我有一个视图模型来表示父子关系
public class PersonVM
{
public int Id { set; get; }
public string Name { set; get; }
public int? ParentId { set; get; }
public List<PersonVM> Childs { set; get; }
}
And in my GET action method, i create an object of my view model and load the Father -childs data to it.
在我的 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);
}
Now i will create an EditorTemplate. To do that, Go to your Views folder, and Create a directory called EditorTemplatesunder the directory which has same name as the controller, and add a view with name PersonVM.cshtml
现在我将创建一个 EditorTemplate。为此,请转到您的 Views 文件夹,并在与控制器同名的目录下创建一个名为EditorTemplates的目录,并添加一个名称为PersonVM.cshtml


Now, go to this view and add the below code.
现在,转到此视图并添加以下代码。
@model ReplaceWithYourNameSpaceNameHere.PersonVM
<div>
<h4>Childs </h4>
@Html.TextBoxFor(s => s.Name)
@Html.HiddenFor(s => s.Id)
</div>
Now let's go back to our main view. We need to make this view strongly typed to our original PersonVM. We will use the EditorFor html helper method in this view to call our editor template
现在让我们回到我们的主视图。我们需要将此视图强类型化到我们的原始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"/>
}
Now have an HttpPost method in the controller to handle the form posting
现在在控制器中有一个 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);
}
Now, If you put a break point in your HttpPost action method, you can see the Id's of childs are passed to this action method.
现在,如果您在 HttpPost 操作方法中放置一个断点,您可以看到孩子的 Id 被传递给此操作方法。


One important thing to remember is, Your Editor Template view's name should be same as the type you are binding to it.
要记住的一件重要事情是,您的编辑器模板视图的名称应该与您绑定到它的类型相同。

