Mais acessados

sexta-feira, 30 de agosto de 2013

ASP.NET MVC - Postando Listas ou Coleções de objetos sem alterar o ModelBinder padrão

Uma das maiores mudanças ocorridas no ASP.NET MVC desde a sua criação, pelo menos em minha opinião, foi a incorporação do ModelBinder. O ModelBinder é responsável pela construção do modelo no server baseado no parâmetro da Action e os nomes dos inputs que foram postados em um formulário. Dessa forma, não é preciso iterar sobre um FormCollection para recuperar as informações enviadas, basta apenas colocar como parâmetro o modelo que deseja receber. Neste breve post vou mostrar como enviar uma coleção qualquer para o servidor sem ter que alterar o ModelBinder padrão do ASP.NET MVC


O problema

Quando criamos um formulário, os HtmlHelpers cuidam do trabalho pesado e já constroem automaticamente todos os atributos necessários nos inputs Html. O principal atributo é o name, que é usado pelo ModelBinder para colocar o valor na propriedade certa quanto o formulário é postado para o server.


Esse attribute name vem direto da Lambda Expression que passamos. Por exemplo, ao criamos um formulário com uma lista usando o foreach , o body da Lambda Exmpression é usado para o name, repare no HtmlHelper e HTML gerado:


View/Task/UpdateMany.cshtml

Html gerado

Isso está errado, quando estamos falando de Listas. O ModelBinder não entenderá que o que será postado é uma coleção de objetos e não conseguirá reconstruir essa lista de novo no server, resultado, você terá um null como abaixo:

Controllers/Task.cs

A solução

Para fazer funcionar basta alterar o foreach por um for, assim os HtmlHelpers vão criar a coisa certa, como abaixo:


View/Task/UpdateMany.cshtml

Html gerado

Veja que agora o name está diferente, parece com um índice de um Array. Quando o form for postado o ModelBinder vai identificar esse padrão dentro da request e reconstruir o formulário como se fosse uma lista, logo você receberá a coisa certa no server.

Controllers/Task.cs

Quando for criar qualquer tipo de formulário com lista, preocupe-se então com o name, mesmo se não estiver usando os HtmlHelpers use sempre esse padrão que o ModelBinder fará todo o trabalho duro para você.

Espero que tenham gostado do post. O exemplo completo pode ser baixado aqui.

Referências:

2 comentários :

  1. Isso funciona perfeitamente quando sabemos ou temos um count para identificar os itens da coleçao. Mas qdo sao n elementos, ou seja, nao sabemos o tamanho da colecao previamente, precisamos usar a feature BegginColection. Por exe uma tela de cliente, e ele cadastra n telefones clicando em um botao Add.

    ResponderExcluir
  2. Essa matéria me ajudou muito. Obrigado pelo post

    ResponderExcluir