ASP.NET MVC Model Binding (parte 3 – binding manual)

Fala, galera

Vimos nos posts anteriores ([aqui] e [aqui]) o processo de binding ocorrendo automaticamente quando os dados enviados em uma requisição são recebidos como parâmetros nas actions.

No entanto, o processo de binding pode ser invocado manualmente quando desejamos obter maior controle sobre o processo.

Vamos usar como exemplo o objeto Contato dos últimos posts para invocarmos o binding de forma manual:


[HttpPost]
public ActionResult Editar()
{
    var contato = new Contato();
    UpdateModel(contato);
    return RedirectToAction("Index");
}

 Notem que “Contato” não é recebido como parâmetro da action. Ao invés disso, nós criamos o objeto dentro da action e chamamos o método UpdateModel para realizar o binding das propriedades do contato.

O mecanismo de binding segue a mesma ideia já mostrada com o binding automático, utilizando a convenção por nomes para buscar os valores em Request.Form, RouteData.Values, Request.QueryString e Request.Files.

USO DO BINDING MANUAL

O único motivo para usarmos o binding manual é uma necessidade muito particular de termos maior controle sobre o processo, como por exemplo:

– Instanciar o objeto manualmente ao invés de recebê-lo como parâmetro (um dos motivos poderia ser: a construção do objeto é muito complexa e exigiria o uso de uma factory)

– Restringir o binding a um determinado local de busca. Por exemplo, queremos que o processo “olhe” somente para os dados vindos de um formulário, ignorando as demais coleções. Isso poderia ser feito passando mais um parâmetro para o método UpdateModel: UpdateModel(contato, new FormValueProvider(ControllerContext)).

TRATANDO ERROS DE BINDING

Quando estamos utilizando o binding automático, todo erro de binding ocorrido é tratado automaticamente, ficando para nós apenas a responsabilidade de checar o ModelState.

No entanto, ao realizarmos o binding manualmente, temos a obrigação de tratar os erros, caso contrário uma exceção do tipo InvalidOperationException será disparada. Corrigindo o exemplo anterior, teremos:

[HttpPost]
public ActionResult Editar()
{
    var contato = new Contato();
    try
    {
       UpdateModel(contato);
    }
    catch(InvalidOperationException ex)
    {
       // retorna para view de edicao para exibir os erros com base no ModelState
       return View("Editar");
    }
    return RedirectToAction("Index");
}

Um modo alternativo, que não lida diretamente com exceções, é utilizar o método TryUpdateModel, que retorna um boolean indicando se houveram erros:

[HttpPost]
public ActionResult Editar()
{
    var contato = new Contato();
    if (TryUpdateModel(contato))
    {
       // sucesso
    }
    else
    {
       // retorna para view de edicao para exibir os erros com base no ModelState
       return View("Editar");
    }
    return RedirectToAction("Index");
}

Vale lembrar que não há nenhuma diferença no processo de binding utilizando UpdateModel ou TryUpdateModel.

CONCLUSÃO

Embora não muito comum, é importante conhecermos o processo de binding manual para termos mais uma opção em nossa caixa de ferramentas quando precisarmos.

Caso suas actions estejam muito poluídas pelo uso de UpdateModel ou TryUpdateModel, uma saída seria encapsular esses tratamentos de erros, por exemplo, em um controller base.

No próximo post da série, falarei um pouco sobre customização do model binding. Aguardem!

[]s

_________________________________________________________________

Este artigo faz parte da série:
1) ASP.NET MVC Model Binding (parte 1 – DefaultModelBinder)
2) ASP.NET MVC Model Binding (parte 2 – outras formas de binding)
3) ASP.NET MVC Model Binding (parte 3 – binding manual)
4) ASP.NET MVC Model Binding (parte 4 – custom binders)

Anúncios

2 comentários em “ASP.NET MVC Model Binding (parte 3 – binding manual)

Participe! Vamos trocar uma ideia sobre desenvolvimento de software!

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s