Say I have the following models:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
public class Town
{
public string Name { get; set; }
public IEnumerable<Person> People { get; set; }
}
Then, in my Razor view, I have this:
@model Town
@using(Html.BeginForm())
{
<table>
@foreach(var person in Model.People)
{
<tr>
<td>@Html.TextBoxFor(m => person.Name)</td>
<td>@Html.TextBoxFor(m => person.Age)</td>
</tr>
}
<table>
<input type="submit" />
}
Then, I have an action for the POST, something like this:
[HttpPost]
public ActionResult Index(Town theTown)
{
//....
}
When I post, the IEnumerable<Person>
does not come across. If I look at it in Fiddler, the collection only posts once, and doesn't enumerate the collection, so I get:
People.Name = "whatever"
People.Age = 99
However, if I change People to an IList
and use a for loop instead of a foreach...
@for(var i = 0;i < Model.People.Count;i++)
{
<tr>
<td>@Html.TextBoxFor(m => Model.People[i].Name)</td>
<td>@Html.TextBoxFor(m => Model.People[i].Age)</td>
</tr>
}
It works. Am I doing something wrong? What am I missing?
All you missed was placing var instead of the Model itself(People) like below
the problem is not with the
IEnumerable
or theIList
it the way you are rendering the collection in your view.Observe that with each list item you are appending a continuous index which enables the model binder to do its magic
A good read