I have a view with a list of items that among their properties have a list of items (in View asp.net core).
I use a generic list to have common properties that I use in the view.
The ViewModels are these:
public class AgaqEleViewModel
{
public int CodEle { get; set; }
public int AbrEle { get; set; }
public string Valor { get; set; }
...
}
public class AgaqViewModel
{
[Required(ErrorMessageResourceType = typeof(AguasResx.DataAnnotations), ErrorMessageResourceName = nameof(AguasResx.DataAnnotations.Required))]
public int Hoja { get; set; } // Key Id compossed
[Required(ErrorMessageResourceType = typeof(AguasResx.DataAnnotations), ErrorMessageResourceName = nameof(AguasResx.DataAnnotations.Required))]
public DateTime FechaTomaAq { get; set; }
public float? ProfmuestraM { get; set; }
...
// List test
public List<AgaqEleViewModel> AgaqEle { get; set; }
...
}
public class GenericListViewModel<T>
{
public RespViewModel Resp { get; set; }
public List<T> ItemsList { get; set; }
public GenericListViewModel()
{
}
public GenericListViewModel(RespViewModel resp, List<T> genericList)
{
Resp = resp;
ItemsList = genericList;
}
}
My Razor View is this:
@model GenericListViewModel<AgaqViewModel>
@{
// get max number of columns of different elements
int numColElements = Model.ItemsList.Select(s => s.AgaqEle.Count).Max();
}
<form asp-action="AgaqLoaded" method="post" id="agaqExcelForm">
@if(Model.Resp.XXX)
{
...
}
<table class="table table-bordered table-sm table-striped">
<thead>
<tr>
@* header columns *@
<th title="@Literals.Hoja">@Literals.Hoja</th>
...
@* create elements columns header´s *@
@for(int i = 0; i < numColElements; i++)
{
<th>@Literals.Element</th>
}
...
<tbody>
// iterate each item in Model list
@for (var i = 0; i < Model.ItemsList.Count(); i++)
{
<tr>
<td class="">
<input asp-for="@Model.ItemsList[i].Hoja" type="hidden" />
@Model.ItemsList[i].Hoja
</td>
<td>
<input asp-for="@Model.ItemsList[i].FechaTomaAq" type="hidden" />
@Model.ItemsList[i].FechaTomaAq
</td>
...
// iterate each list elements in each item in Model list
@for(int j = 0; j < numColElements; j++)
{
<td>
<input asp-for="@Model.ItemsList[i].AgaqEle[j].CodEle" type="hidden" />
<input asp-for="@Model.ItemsList[i].AgaqEle[j].AbrEle" type="hidden" />
<input asp-for="@Model.ItemsList[i].AgaqEle[j].Valor" type="hidden" />
...
@elemAgaq.AbrEle: @elemAgaq.Valor
</td>
}
}
...
<tfoot>
<button id="btnLoad" type="submit" class="btn btn-sm btn-primary"><i class="fa fa-upload"></i> @AguasLiterals.LoadData</button>
...
</form>
and my Controller is this:
[HttpPost("{controller}/{action}/")]
public async Task<IActionResult> AgaqLoaded(GenericListViewModel<AgaqViewModel> listToLoad)
{
// save
foreach (AgaqViewModel agaqEx in listToLoad.ItemsList)
{
AgaqDto saveAgaq = null;
AgaqDto agaq = _mapper.Map<AgaqDto>(agaqEx);
// save Agaq
saveAgaq = await _service.SetAgaqAsync(agaq);
...
The generated HTML code is:
<td>
<input type="hidden" data-val="true" data-val-range="El valor ..." data-val-range-max="9999" data-val-range-min="1" data-val-required="Este campo es obligatorio." id="ItemsList_0__Hoja" name="ItemsList[0].Hoja" value="1921">
1921
</td>
<td>
<input type="hidden" data-val="true" data-val-required="Este campo es obligatorio." id="ItemsList_0__FechaTomaAq" name="ItemsList[0].FechaTomaAq" value="20/07/2021 0:00:00">
20/07/2021 0:00:00
</td>
<td>
<input type="hidden" data-val="true" data-val-required="The CodEle field is required." id="ItemsList_0__AgaqEle_0__CodEle" name="ItemsList[0].AgaqEle[0].CodEle" value="3">
<input type="hidden" id="ItemsList_0__AgaqEle_0__AbrEle" name="ItemsList[0].AgaqEle[0].AbrEle" value="Na">
<input type="hidden" id="ItemsList_0__AgaqEle_0__Valor" name="ItemsList[0].AgaqEle[0].Valor" value="48">
...
Na: 48
</td>
<td>
<input type="hidden" data-val="true" data-val-required="The CodEle field is required." id="ItemsList_0__AgaqEle_1__CodEle" name="ItemsList[0].AgaqEle[1].CodEle" value="3">
<input type="hidden" id="ItemsList_0__AgaqEle_1__AbrEle" name="ItemsList[0].AgaqEle[1].AbrEle" value="Ca">
<input type="hidden" id="ItemsList_0__AgaqEle_1__Valor" name="ItemsList[0].AgaqEle[1].Valor" value="16">
...
Ca: 16
</td>
The objects arrive correctly to the view and the generated HMTL is apparently correct. (The rest of the items/elements have the correct numbering: ItemsList_1__AgaqEle_0__CodEle, ItemsList_1__AgaqEle_0__AbrEle ... ItemsList_7__AgaqEle_0__CodEle ...)
When in the view I comment out the part of the elements (second loop, asp-for hidden properties) inside each item in the list, I get it correctly.
But if I don't comment the elements, although the HTML is apparently correct, the post request call arrives null without any item or elements.
I have several "simple" lists of complex elements that work fine, but this list composed of items with a list of elements I can't binding it.
What am I doing wrong?
I've tried removing the generic viewmodel and leaving it as a list of items, I've tried using list[i][j] or list[i].[j] and everything I could think of but nothing works? Any ideas? Thanks.


ItemsList[i].AgaqEle[j]is the correct way for model binding. Maybe your project contains any other code you do not share, and not sure why you use two@for (var i = 0; i < Model.ItemsList.Count(); i++)loop here. Suggest you can share your whole razor view.