I have two models: OuterModel and InnerModel. There is a one to many relationship between OuterModel and InnerModel, respectively. To clarify my question, my model is of type IEnumerable<OuterModel>. I’m passing a random number of OuterModels to the view and the user creates any number of InnerModels for each OuterModel. Then on submission, I want the controller to receive the list of OuterModels so that the InnerModels can be added to the database to their intended OuterModels.
I believe I have the naming convention correct to make use of MVC’s built in model binding. Here’s what that looks like:
OuterModel[i].InnerModel[j].Property
My problem is, I don’t really know how to get a list of OuterModels passed to the controller. Here’s what I’ve tried in my View:
@model IEnumerable<OuterModel>
@using (Html.BeginForm("Create", "Controller", new { OuterModels = Model }, FormMethod.Post))
{
//Code to create the InnerModels here
}
And here’s what I have in my Controller:
[HttpPost]
public ActionResult Create(IEnumerable<OuterModel> OuterModels, FormCollection fc)
{
String[] keys = fc.AllKeys;
if(ModelState.IsValid){
//Add to db
}
}
Keys shows that all of my properties are following the naming convention that I specified earlier, but ModelState.IsValid is returning false. It shows that OuterModels’ count is 0.
Even though I’m telling the form to submit OuterModels = Model before any InnerModels are created, you would think there would still be data in OuterModels considering it’s passed to the view. I am really tired today, so I’m guessing I’m looking over one (or many) small detail(s). Any suggestions?
–EDIT–
Passing a list of OuterModels to the controller may not be the best approach. If anybody has a better suggestion, please share.
As long as indexes are used properly, then this should not be an issue. Here is how I would envision the form names.
Model[0].foo
Model[0].Inner[0].bar
Model[0].Inner[1].bar
Where outer model has a property called foo and
Outer model has a property called inner which is a collection of inner objects. Inner object has a property called bar. If your form is rendered with the correct indexes then the model binding should work. Things can get tricky if form fields are generated client side. I recommended going back to server in order to manipulate the model. There are some extra round trips, but you can make them via Ajax request.
Here are some more details in a more fleshed out example.
Here is what I would envision my view would look like:
If this is wrapped in a form— and the controller action looks like this:
then I would think model would be populated correctly.
I noticed your form.. it doesn’t look right to me… I wouldn’t think that the passing the OuterModels like that is going to work– although frankly I might be wrong.
Here is an example I did for the class I teach.. that definitely works..
Controller:
and View: