Send only list object that has changed to the controller

4

I have a view that lists all my clients . Each client has 3 checkbox where the user selects the same, and sends to controller - through the button (submit) - the data to change. The method is working perfectly. However, when sending, it sends all clients, even those that have not changed. So it updates all (even those that have not been modified). This does not cause me problems, but causes a delay (since it has to go through the whole list to change).

I would like to know if there is a way to check if the client has been modified, and only send the ones that were to my controller .

My View looks like this:

@using PrestacaoWeb.UI.Helpers
@model List<PrestacaoWeb.Application.ViewModels.ClientePrestacaoViewModel>

@using (Html.BeginForm("EditarMes", "Cliente", FormMethod.Post))
{
    <input type="submit" value="Salvar"/>

<table>
    <thead>
        <tr>
        <th> Cliente </th>
        <th> 1 </th>
        <th> 2 </th>
        <th> 3 </th>
        <th> Cidade </th>
        <th> Responsável </th>
        <th> Obs </th>
        </tr>
    </thead>
        <tbody>
        @for (int i = 0; i < Model.Count(); i++)
        {
            <tr>
                @Html.HiddenFor(model => model[i].ClienteId)
                <td style="width: 100px">
                    <p align="center">@Model[i].NomeCliente</p>
                </td>
                <td style="width: 20px"><p align="center"> <b>@Html.CheckBoxFor(model => Model[i].EnvioPrestacao.bJaneiro)</b> </p> </td>

                <td style="width: 20px"><p align="center"> <b>@Html.CheckBoxFor(model => Model[i].EnvioPrestacao.bFevereiro)</b> </p> </td>

                <td style="width: 20px"><p align="center"> <b>@Html.CheckBoxFor(model => Model[i].EnvioPrestacao.bMarco)</b> </p> </td>
                 <td>
                    @Model[i].Cliente.Cidade.Nome
                </td>

                <td style="width: 100px">
                    <p align="center">@Model[i].Responsavel</p>
                </td>
                    <td style="width: 210px">
                        <p align="center">@Model[i].Observacao.</p>
                    </td>

            </tr>

        }
        </tbody>
</table>
}

By clicking the Save button, it sends all objects in the list to the EditMes method, in my Controller .

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult EditarMes(IList<ClientePrestacaoViewModel> prestacaoViewModel)
{
    if (!ModelState.IsValid) return View("Index");
    foreach (var item in prestacaoViewModel.Where(item => item != null))
    {
        _clienteContext.Atualizar(item);
        TempData["MensagemSuccess"] = "Cliente alterado com sucesso!";

    }
    return Redirect(ControllerContext.HttpContext.Request.UrlReferrer.ToString());
}

If I change all the clients, that's right, it will take a while. Now, if you change only one client, and it sends 30 to controller , it would not be "cool" to wait for it.

    
asked by anonymous 22.07.2015 / 16:52

1 answer

4

It is cheaper in cost of processing to bring the original list and compare values.

Apparently you use a repository, so I do not know how this is done, but using an Entity Framework context would look something like this:

var listaOriginal = contexto.ClientePrestacoes.AsNoTracking().Where(/* Condição */).ToList();

foreach (var item in prestacaoViewModel.Where(item => item != null))
{
    var itemOriginal = listaOriginal.Single(l => l.Id == item.Id);
    if (item.bJaneiro != itemOriginal.bJaneiro || item.bFevereiro != itemOriginal.bFevereiro || item.bMarco != itemOriginal.bMarco) {
        _clienteContext.Atualizar(item);
    }

    TempData["MensagemSuccess"] = "Cliente alterado com sucesso!";
}

Taking advantage of this is not a good practice:

if (!ModelState.IsValid) return View("Index");

In this command, you stop implementing the default MVC behavior, which is to return the same screen in case of invalidity of any information on screen, and does not load any data that fills the screen.

    
22.07.2015 / 17:05