The <string> list is returned as System.Collections.Generic.List on HttpPost with MVC

I have a web application written in MVC5 that passes a list of objects (which contains many elements) to the page and successfully displays. I have a button in the form that returns Post. When I click the button, the model seems to reinitialize the list of objects, rather than returning what was on the page.

I read various posts on SO that cover similar issues that many suggestions have made, such as ensuring that every element of the object is in a form (at least hidden). I tried many options, but still could not solve my problem.

I decided to go back to the basics and created a very simple View model with a list. This displays normally again, but when it returns to System.Collections.Generic.List.

Show model

public class TestVm
{
    public List<string> CustomerNames { get; set; }
}

controller

public ActionResult Index()
{
    TestVm testmodel = new TestVm();

    testmodel.CustomerNames = new List<string>();
    testmodel.CustomerNames.Add("HELP");
    testmodel.CustomerNames.Add("Its");
    testmodel.CustomerNames.Add("Not");
    testmodel.CustomerNames.Add("Working");
    return View(testmodel); 
}

[HttpPost]
public ActionResult Index(TestVm model)
{
    // DO SOME WORK HERE WITH RETURNED model
    return View(model);
}

View

@model WebApplication1.Models.TestVm
@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>View</title>
</head>
<body>

@using (Html.BeginForm("Index", "Test", Model, FormMethod.Post, new { @class = "form-horizontal" }))
{
    <button name="submit" type="submit" value="Refresh" class="btn btn-sm btn-default pull-right">Refresh</button>
}
<div>
@if (Model.CustomerNames != null)
{

<table>
    <thead>
    <tr>
        <td class="text-center">CustomerName</td>
    </tr>
    </thead>
    <tbody>
    @for (int i = 0; i < Model.CustomerNames.Count(); i++)
    {
        <tr>
            <td class="text-center">@Html.EditorFor(m => m.CustomerNames[i])</td>
            </tr>
        }
        </tbody>
        <tfoot>
        </tfoot>
    </table>
}
</div>
</body>
</html>

I thought creating a simple application like this would help me understand and solve my problem. But I can’t understand why the model in HttpPost contains “System.Collections.Generic.List” and not the actual list of strings that I would expect.

Bootstrap Page when loading for the first time

After update

Page after I clicked Refresh

+4
source share
1 answer

You need to enclose each form control in Html.BeginFormbrackets

@using (Html.BeginForm("Index", "Test", Model, FormMethod.Post, new { @class = "form-horizontal" }))
{
    <button name="submit" type="submit" value="Refresh" class="btn btn-sm btn-default pull-right">Refresh</button>

    <div>
    @if (Model.CustomerNames != null)
    {

        <table>
            <thead>
                <tr>
                    <td class="text-center">CustomerName</td>
                </tr>
            </thead>
            <tbody>
                @for (int i = 0; i < Model.CustomerNames.Count(); i++)
                {
                    <tr>
                        <td class="text-center">@Html.EditorFor(m => m.CustomerNames[i])</td>
                    </tr>
                }
            </tbody>
            <tfoot>
            </tfoot>
        </table>
    }
    </div>
}
+2
source

Source: https://habr.com/ru/post/1627361/


All Articles