0

I'm working with the following View:

@model IEnumerable<Gestor.Models.VarTc>
@{
    ViewBag.Title = "Alterar TC";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Alterar TC</h2>

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

<table class="table table-hover">
<tr>
    <th>Item</th>
    <th>Descrição</th>
    <th>Critério</th>
    <th>Var TC1</th>
    <th>Var TC2</th>
    <th>Var TC3</th>
    <th>Var TC4</th>
</tr>

@foreach (var item in Model)
{
    @Html.HiddenFor(m => item.Id)

    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Apelido)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Descricao)
        </td>
        <td>
            <div class="form-group">
                <div class="col-md-10">
                    @Html.EditorFor(model => item.Criterio, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => item.Criterio, "", new { @class = "text-danger" })
                </div>
            </div>
        </td>
        <td>
            <div class="form-group">
                <div class="col-md-10">
                    @Html.EditorFor(model => item.VarTc1, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => item.VarTc1, "", new { @class = "text-danger" })
                </div>
            </div>
        </td>
        <td>
            <div class="form-group">
                <div class="col-md-10">
                    @Html.EditorFor(model => item.VarTc2, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => item.VarTc2, "", new { @class = "text-danger" })
                </div>
            </div>
        </td>
        <td>
            <div class="form-group">
                <div class="col-md-10">
                    @Html.EditorFor(model => item.VarTc3, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => item.VarTc3, "", new { @class = "text-danger" })
                </div>
            </div>
        </td>
        <td>
            <div class="form-group">
                <div class="col-md-10">
                    @Html.EditorFor(model => item.VarTc4, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => item.VarTc4, "", new { @class = "text-danger" })
                </div>
            </div>
        </td>
    </tr>
}

</table>

<div class="form-group">
    <div class="col-md-offset-2 col-md-10">
        <input type="submit" value="Gravar e Calcular" class="btn btn-default" />
    </div>
</div>
}

<div>
    @Html.ActionLink("Retornar a lista", "Index")
</div>

Which is called by this Action:

public ViewResult VarTc()
    {
        var tcs = new List<VarTc>();
        var lista = db.PlanejVendas.ToList();

        foreach (var item in lista)
        {
            var produto = db.Produtos.Single(p => p.Id == item.ProdutoId);
            var tc = new VarTc
            {
                Id = item.ProdutoId,
                Apelido = produto.Apelido,
                Descricao = produto.Descricao,
                Criterio = item.Criterio,
                VarTc1 = item.VartC1,
                VarTc2 = item.VarTc2,
                VarTc3 = item.VartC3,
                VarTc4 = item.VartC4
            };

            tcs.Add(tc);
        }

        return View(tcs);

The post Action is handed as follows:

[HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult VarTc(List<VarTc> varTc)
    {
        if (ModelState.IsValid)
        {
            foreach (var item in varTc)
            {
                var atual = db.PlanejVendas.Single(p => p.Id == item.Id);
                atual.Criterio = item.Criterio;
                atual.VartC1 = item.VarTc1;
                atual.VarTc2 = item.VarTc2;
                atual.VartC3 = item.VarTc3;
                atual.VartC4 = item.VarTc4;

                db.SaveChanges();
            }

            RedirectToAction("Index");
        }

        return RedirectToAction("VarTc");
    }

When, in execution I fill the form and run the action I verify that there is no List varTc. It's actually null.

So that the, what I at least believe List with the values is not handled as return.

I tried everything I could think of and I wasn't able to get the data.

How data can be done?

Does it has to do with the fact that I'm trying to read a list or it i8s just something else?

Sergio Di Fiore
  • 446
  • 1
  • 8
  • 22

1 Answers1

1

When you do this:

@foreach (var item in Model)
{
    @Html.HiddenFor(m => item.Id)
}

all the html tags generated will have the same name. In this case, they will all have the same name="Id", id="Id". You do not want that. Do this instead:

for (int i = 0; i < Model.Count; i++)
{
    @Html.HiddenFor(m => Model[i].Id)
}

You need to do that for all the fields so each one can have a different name. Then when you submit the form, the MVC binder will figure out that you have many things (VarTc) and the binding will work as you expect.

If you need more details about the issue you are experiencing, please read this answer.

CodingYoshi
  • 25,467
  • 4
  • 62
  • 64