Reputation: 25370
I have a PersonViewModel that consists of several List<SubViewModel>
(Name, Address, etc.)
I have an Html Form with tables for each SubViewModel, where the user can update,add,delete and set items to the primary entry for the person.
a simplified table for names:
@foreach (PersonNameViewModel name in Model.Names)
{
<tr>
<td>
@Html.DisplayFor(modelItem => name.FullName)
</td>
<td>
@Html.DisplayFor(modelItem => name.FirstName)
</td>
<td>
@Html.DisplayFor(modelItem => name.MiddleName)
</td>
<td>
@Html.DisplayFor(modelItem => name.LastName)
</td>
<td class="center">
@Html.RadioButtonFor(modelItem => name.IsPrimary, "")
</td>
<td class="center">
@Html.CheckBoxFor(modelItem => name.ToDelete)
</td>
</tr>
}
From here, I don't know how to get all the data back into the PersonViewModel when the user submits the form, to update the person record. If I simply accept a PersonViewModel
in my POST controller, it's completely empty. I looked at FormCollection, but I'm not sure if that's right for this. Can someone with experience point me in the right direction for building my model back up for updating? Thankyou very much.
Upvotes: 1
Views: 418
Reputation: 15188
Everyone's answer is correct, But if you want to update people's information, you need to use Html Helper Editor
NOT Display
. Also, you still can use foreach
in your view, just change it like below:
@foreach (var name in Model.Names.Select((value, i) => new { i, value }))
{
<tr>
<td>
@Html.EditorFor(m => m.Names[@name.i].FullName)
</td>
<td>
@Html.EditorFor(m => m.Names[@name.i].FirstName)
</td>
<td>
@Html.EditorFor(m => m.Names[@name.i].MiddleName)
</td>
<td>
@Html.EditorFor(m => m.Names[@name.i].LastName)
</td>
<td class="center">
@Html.RadioButtonFor(m => m.Names[@name.i].IsPrimary,"")
</td>
<td class="center">
@Html.CheckBoxFor(m => m.Names[@name.i].ToDelete)
</td>
</tr>
}
Upvotes: 3
Reputation: 39299
Try replacing the foreach with a for loop:
@for (int i = 0; i < Model.Names.Count; i++)
{
<tr>
<td>
@Html.DisplayFor(m => m.Names[i].FullName)
</td>
<td>
@Html.DisplayFor(m => m.Names[i].FirstName)
</td>
<td>
@Html.DisplayFor(m => m.Names[i].MiddleName)
</td>
<td>
@Html.DisplayFor(m => m.Names[i].LastName)
</td>
<td class="center">
@Html.RadioButtonFor(m => m.Names[i].IsPrimary, "")
</td>
<td class="center">
@Html.CheckBoxFor(m => m.Names[i].ToDelete)
</td>
</tr>
}
The expression parsing/model binding does a better job with indexes than with foreach temp variables.
Upvotes: 1
Reputation: 35853
You should use sth like this (good article about model binding of collections and complex data here):
@for(var i = 0;i < Model.Names.Count;i++)
{
<tr>
<td>
@Html.DisplayFor(m => Model.Names[i].FullName)
</td>
<td>
@Html.DisplayFor(m => Model.Names[i].FirstName)
</td>
<td>
@Html.DisplayFor(m => Model.Names[i].MiddleName)
</td>
<td>
@Html.DisplayFor(m => Model.Names[i].LastName)
</td>
<td class="center">
@Html.RadioButtonFor(m => Model.Names[i].IsPrimary, "")
</td>
<td class="center">
@Html.CheckBoxFor(m => Model.Names[i].ToDelete)
</td>
</tr>
}
Upvotes: 1