ASP.Net MVC3 Parent Child Model Binding

kolhapuri picture kolhapuri · Apr 11, 2011 · Viewed 7.6k times · Source

I have a partial template that uses a User object as a model. The user has a collection of Accounts. On this partial template I have a loop as follows. The _Account partial template is bound to the Account class

  @foreach (var item in Model.Accounts)
            { 
                <tr>
                    <td colspan="6">
                        <div>
                            @Html.Partial("_Account", item)
                        </div>
                    </td>
                </tr>

            }

In my controller method I initially tried

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UserDetails(User user, string actionType)

But the User.Accounts collection is empty. Then I tried this. Still the Accounts collection is empty.

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UserDetails(User user,  
                             [Bind(Prefix="User.Accounts")]
                             FixupCollection<Account> Accounts, 
                             string actionType)

Can I use the default Modelbinder implementation to achieve this or do I need to do anything different?

Answer

Milimetric picture Milimetric · Apr 11, 2011

Yep, you can use the default model binder. You just need to name your fields correctly. So you need your loop to output something like this:

...
<input type="text" name="user.Accounts[0].SomeTextField" />
<input type="text" name="user.Accounts[0].SomeOtherTextField" />
...
<input type="text" name="user.Accounts[1].SomeTextField" />
<input type="text" name="user.Accounts[1].SomeOtherTextField" />
...

If you need to add/remove accounts, the hardcoded indexes get a little trickier. You could re-assign the names using javascript before postback. But it's all possible. This question gives more detail on model binding:

ASP.NET MVC: Binding a Complex Type to a Select