MVC post form with list of lists
Most of the tutorials, Questions I found on the internet, are about when a Model has one Item List. But in my case, I have a list of items that also contain a list of items.
I have a ViewModel with a list ItemA
and ItemA
has a listItemsB
public class ViewModel
{
List<ItemA> Items { get; set; }
public ViewModel()
{
Items = new List<ItemA>();
}
}
public class ItemA
{
public int ItemAId { get; set; }
public List<ItemB> ItemBList { get; set; }
public ItemA()
{
ItemBList = new List<ItemB>();
}
}
public class ItemB
{
public int ItemBId { get; set; }
// Need to input this string for each Item in List<ItemA>
public string NewInput
}
My view:
@Html.BeginForm(){
@foreach (var itemA in Model.Items)
{
<p>@itemA.ItemAId</p>
for (int i = 0; i < itemA.ItemBList.Count; i++)
{
@Html.HiddenFor(m => itemA.ItemBList[i].ItemBId )
@Html.TextBoxFor(m => itemA.ItemBList[i].NewInput)
}
<button type="submit">Submit</button>
}
}
My controller:
public ActionResult SaveInfo(ViewModel model){
// Update
}
My question is, how do I write a form for this case so that it binds to the ViewModel in the controller?
source to share
Its pretty simple - you just need to nest 2 for
loops in the view (don't use foreach)
those. change to:
@Html.BeginForm(){
@for(int j = 0; j < Model.Items.Count; j++)
{
<p>@Model.Items[j].ItemAId</p>
@Html.HiddenFor(m => m.Items[j].ItemAId)
@* (don't forget this!) *@
for (int i = 0; i < Model.Items[j].ItemBList.Count; i++)
{
@Html.HiddenFor(m => m.Items[j].ItemBList[i].ItemBId )
@Html.TextBoxFor(m => m.Items[j].ItemBList[i].NewInput)
}
}
<button type="submit">Submit</button>
}
MVC Model Binder requires that form fields that represent the properties on the list, call it something like [#].property1name
, [#].property2name
in order to properly link them with each other during the binding after postback. The same principle applies to the properties of a list of lists. You need to use a loop for
, not a loop foreach
, to get the correct form field names when using HTML helpers!
source to share