Search code examples
c#.netasp.net-mvcasp.net-core-mvc

List object empty in controller action after submit button clicked when using the 'Tuple' type in data model declaration


I have a view that has a tuple as a model. The data shows correctly in the view.

The problem is, I have a form that loops through the list object, but when I press the submit button, the action shows that the list count is 0. No data gets passed to the action.

My view:

@model Tuple<List<CompanyPricingLevels>, CompanyModuleDetails>

@if (Model.Item2.Module.ModuleName == "Consolidation")
{
    <div class="container">
        <h1>Company Pricing Levels</h1>
        @using (Html.BeginForm("SaveLevels", "Admin", FormMethod.Post))
        {
            <table class="table">
                <thead>
                    <tr>
                        <th>Level Type</th>
                        <th>Level 1</th>
                        <th>Level 2</th>
                        <th>Level 3</th>
                        <th>Level 4</th>
                        <th>Level 5</th>
                        <th>Level 6</th>
                    </tr>
                </thead>
                <tbody>
                    @for (int i = 0; i < Model.Item1.Count; i++)
                    {
                        <tr>
                            <td>@Model.Item1[i].LevelType</td>
                            <td>@Html.TextBoxFor(model => model.Item1[i].Level1, new { @class = "form-control", @Name = $"Item1[{i}].Level1" })</td>
                            <td>@Html.TextBoxFor(model => model.Item1[i].Level2, new { @class = "form-control", @Name = $"Item1[{i}].Level2" })</td>
                            <td>@Html.TextBoxFor(model => model.Item1[i].Level3, new { @class = "form-control", @Name = $"Item1[{i}].Level3" })</td>
                            <td>@Html.TextBoxFor(model => model.Item1[i].Level4, new { @class = "form-control", @Name = $"Item1[{i}].Level4" })</td>
                            <td>@Html.TextBoxFor(model => model.Item1[i].Level5, new { @class = "form-control", @Name = $"Item1[{i}].Level5" })</td>
                            <td>@Html.TextBoxFor(model => model.Item1[i].Level6, new { @class = "form-control", @Name = $"Item1[{i}].Level6" })</td>
                        </tr>
                    }
                </tbody>
            </table>
            <button type="submit" class="btn btn-primary">Save</button>
        }
    </div>
}

My controller action:

[HttpPost]
public IActionResult SaveLevels(List<CompanyPricingLevels> levels)
{
    return View();
}

Is there anything obvious I am doing wrong? Any help and guidance will be greatly appreciated.


Solution

  • Use as following:

    [HttpPost]
    public IActionResult SaveLevels([Bind(Prefix="Item1")]List<CompanyPricingLevels> levels)
    {
        if (!ModelState.IsValid)
        ...
    
        return View();
    }
    

    And I suppose you don't need to specify names like @Name = $"Item1[{i}].Level1" explicitly. The @Html.TextBoxFor() helper will do it by default.