Model Binding to a List MVC 4

This is how I do it if I need a form displayed for each item, and inputs for various properties. Really depends on what I’m trying to do though.

ViewModel looks like this:

public class MyViewModel
{
   public List<Person> Persons{get;set;}
}

View(with BeginForm of course):

@model MyViewModel


@for( int i = 0; i < Model.Persons.Count(); ++i)
{
    @Html.HiddenFor(m => m.Persons[i].PersonId)
    @Html.EditorFor(m => m.Persons[i].FirstName) 
    @Html.EditorFor(m => m.Persons[i].LastName)         
}

Action:

[HttpPost]public ViewResult(MyViewModel vm)
{
...

Note that on post back only properties which had inputs available will have values. I.e., if Person had a .SSN property, it would not be available in the post action because it wasn’t a field in the form.

Note that the way MVC’s model binding works, it will only look for consecutive ID’s. So doing something like this where you conditionally hide an item will cause it to not bind any data after the 5th item, because once it encounters a gap in the IDs, it will stop binding. Even if there were 10 people, you would only get the first 4 on the postback:

@for( int i = 0; i < Model.Persons.Count(); ++i)
{
    if(i != 4)//conditionally hide 5th item, 
    { //but BUG occurs on postback, all items after 5th will not be bound to the the list
      @Html.HiddenFor(m => m.Persons[i].PersonId)
      @Html.EditorFor(m => m.Persons[i].FirstName) 
      @Html.EditorFor(m => m.Persons[i].LastName)           
    }
}

Leave a Comment