MVC3 Razor httppost return complex objects child c

2019-05-31 07:13发布

问题:

I have not been using MVC3 for that long and think this is a flaw in my knowledge than a real issue.

I have an object that has a few basic properties and then a collection of inner objects, (simplified version):

public class myClass
{
    public string Name { get; set; }
    public string Location { get; set; }
    public List<myOtherClass> Children { get; set; }
 }

public class myOtherClass
{
    public string Name { get; set; }
    public int Age { get; set; }
}

I have a view that is strongly typed to the "myClass" object. I use the @html.editorfor for the name and location then a foreach for the children objects. in the foreach I again use editorfor's for each of their properties.

On postback(httppost action) the myClass name and location are filled out but the children list is empty.

I am not sure how I should craft the view to ensure it populates all the child elements.

I tried both:

[httppost]
public actionresult myaction(myClass myclass)
{
}

and:

[httppost]
public actionresult myaction()
{
    myClass myclass = new myClass();
    TryUpdateModel(myclass);
}

回答1:

You should not iterate over children manually, you should define editor template for myOtherClass and then just let framework generate editors for all items collection.

Create EditorTemplate for myOtherClass at ~/Views/Shared/EditorTemplates/myOtherClass.cshtml

@model myOterClass
@Html.EditorFor(model => model.Name)
@Html.EditorFor(model => model.Age)

Then in parent view

@Html.EditorFor(model => model.Children)

This will internally call your editor template for all items in collection, and generate correct input names for model binding.



回答2:

in View:

@for (int i = 0; i < Model.Children.Count; i++)
{
  <div class="editor-field">
    @Html.EditorFor(m => m.Children[i].Name)
  </div>

}

and in controller:

public ActionResult Test()
{
    var model = new myClass();
    model.Name = "name";
    model.Location= "loc";

    model.Children = new List<myOtherClass>();
    var child1 = new myOtherClass();
    child1.Name = "Name1";

    var child2 = new myOtherClass();
    child2.Name = "Name2";

    model.Children.Add(child1);
    model.Children.Add(child2);
    return View(model);
}

[HttpPost]
public ActionResult Test(myClass model)
{
    //model.Children Has Value
}