Uso de POST em ASP.NET MVC

Sem dúvida alguma de todos os mecanismos que há para mandar informação a partir de uma visão para um controlador, o uso de POST é o mais comum.

Por Eduard Tomás - Tradução CRV


Publicado em: 23/4/12
Valorize este artigo:
Dito rápido e mal: o uso de POST equivale ao uso de formulários HTML. Digo mal porque nem os formulários são a única maneira de enviar dados via POST, nem todos os formulários são enviados por POST, mas não nos vamos centrar nestes detalhes já que a maioria de formulários hoje em dia são enviados via POST. A principal diferença entre enviar dados via POST ou via GET (ou seja usando a URL, seja através de querystring que vimos no artigo anterior, ou em valores de rota) é que com POST os dados circulam no corpo da solicitação e não são visíveis na URL.

Enviar dados através de um formulário

Falar de dados enviados através de um formulário a um controlador implica apresentar uma característica de ASP.NET MVC que se vai converter em um grande aliado: o model binding. Por esse nome nos referimos à capacidade de ASP.NET MVC de construir objetos a partir dos dados que cheguem a ele na solicitação. Para ser honestos o model binding funciona com independência tanto se os dados vêm de um formulário, na querystring ou por valores de rota, mas é quando se mandam dados através de formulários que adquire sua máxima expressão.

Mas vamos por partes... Vamos começar por uma visão simples que será mostrada em resposta à ação Novo do controlador Usuários:

<h2>Novo usuario</h2>

<form method="POST">
<label for="login">login:</label>
<input type="text" name="login" />
<br />
<label for="password">chave:</label>
<input type="text" name="password" />
<br />
<input type="submit" value="enviar"/>
</form>

Esta visão cria um formulário que será enviado por POST. O formulário contém:

  • Duas etiquetas com texto (
  • Dois campos de texto (<input type=?text?>), um que se chama ?login? e outro chamado ?password? (o valor de seus atributos name).
  • Um botão para enviar o formulário
Se vocês observarem não indicamos a que URL deve ser enviado o formulário. Isso é feito através do atributo action da etiqueta <form>. Se não aparece, o formulário será mandado de volta à mesma URL em que estamos.

No controlador (UsuariosController) inserimos simplesmente uma ação que mostre a visão:

public ActionResult Novo()
{
return View();
}

Bem, se agora com o navegador nos dirigimos a /Usuarios/Novo nos aparecerá a visão com o formulário. Podemos preencher dados e pressionar enviar. Ao pressionar enviar simplesmente será mostrada a visão (vazia) de novo. Isto ocorre porque ao pressionar o botão de enviar dados o formulário é enviado à mesma URL (/Usuarios/Novo) da que viemos. Portanto, se invoca de novo a ação Novo do controlador Usuarios que o único que faz é mostrar a visão outra vez.

Bom agora, o que nós queremos é que quando se envie o formulário via POST possamos obter os dados e fazer algo com eles. Em resumo queremos fazer outra coisa que não seja mostrar a visão. A verdade é que soa um pouco como se quiséssemos outra ação diferente. Porém, se vocês lembram no começo deste manual, dissemos que uma ação só podia estar implementada por um único método no controlador. Bem, a verdade é que... mentimos um pouquinho. A realidade é que uma ação pode estar implementada por um só método por cada verbo HTTP. Se você não sabe o que são os verbos HTTP não se preocupe muito: é a maneira técnica de nos referirmos a GET e POST. Assim GET é um verbo HTTP e POST é outro. Há mais, como HEAD, PUT e DELETE mas dado que não há suporte em HTML para estes verbos não vamos nos preocupar com eles (isso não significa que ASP.NET MVC não os suporte, só que não vamos vê-lo aqui). Para nós só vão existir GET e POST. E voltando ao que diziamos, isso significa que para a mesma ação (portanto, a mesma URL) posso ter dois métodos no controlador: um que se invoque através de GET e outro que se invoque através de POST. Assim, podemos acrescentar o seguinte método a nosso controlador:

[HttpPost]
public ActionResult Novo(string login, string password)
{
// Codigo...
}

Observem como o método está decorado com [HttpPost]. Ao aplicar este atributo ao método estamos indicando a ASP.NET MVC que quando se deva invocar a ação Novo do controlador Usuários use este método se a invocação é via POST. Se a invocação é via GET (p.ex. teclando a URL na barra de endereços do navegador) se invocará o método Novo que já tínhamos. Observem que temos uma maneira simples e elegante de separar nosso código em função do verbo HTTP que se use.

Observemos agora nos parâmetros do método Novo: dois parâmetros cujo nome é o mesmo que os nomes dos campos do formulário. Só com isto basta a ASP.NET MVC para lincar os valores do formulário com os parâmetros da ação do controlador. Agora bem, imagine que nosso formulário em lugar de ter dois campos, tem vinte... Você imagina ter que colocar vinte parâmetros na ação do controlador? Pois bem, para evitar isto existe precisamente o model binding.

Model Binding

Chamamos model binding à capacidade de ASP.NET MVC de criar objetos (de nossas classes) a partir dos parâmetros que venham na solicitação. No nosso caso a partir dos campos do formulário que enviamos.

Assim poderíamos ter uma classe Usuário exatamente como a que segue:

public class Usuario
{
public string login { get; set; }
public string password { get; set; }
}

E substituir os dois parâmetros que tínhamos na ação Novo por um só parâmetro de tipo Usuário:

[HttpPost]
public ActionResult Novo(Usuario usuario)
{
// Codigo...
}

E graças ao poder do model binding receberemos um objeto usuário preenchido a partir dos dados do formulário. A única condição é que as propriedades do objeto sejam chamadas igual aos campos do formulário.

Chegados a este ponto poderíamos validar os dados e se houver algum erro, podemos mandá-los de volta à visão (junto com uma mensagem explicativa do erro):

[HttpPost]
public ActionResult Novo(Usuario usuario)
{
if (string.IsNullOrEmpty(usuario.login) ||
string.IsNullOrEmpty(usuario.password))
{
ViewBag.Error = "Login ou password não podem estar vazios";
return View(usuario);
}
// Inscrevemos o usuario na BBDD e redirecionamos
return RedirectToAction("Home", "Index");
}

Se o campo de login ou password se deixa vazio, então acrescentamos um campo chamado Error no ViewBag e retornamos a visão, passando-lhe como dados o objeto usuário que recebemos. Se por outro lado a validação estiver correta redirigimos o usuário à ação Index do controlador Home.

Bom, agora vamos à visão: a ideia é que se a visão recebe um objeto do tipo Usuário preencha os campos de texto com o valor dos campos de tal usuário. Deste modo ao lhe mandar de volta o objeto desde o controlador, o usuário verá exatamente o mesmo que ele enviou e só deverá corrigir os erros que sejam indicados. O novo código da visão é:

@model MvcDadosPost.Models.Usuario
<h2>Novo usuario</h2>

@if (!string.IsNullOrEmpty(ViewBag.Error))
{
<div class="error">@ViewBag.Error</div>
}
<form method="POST">
<label for="login" >login:</label>
<input type="text" name="login" value="@(Model!=null ? Model.login : string.Empty)"/>
<br />
<label for="password">chave:</label>
<input type="text" name="password" />
<br />
<input type="submit" value="enviar"/>
</form>

O que acrescentamos com respeito à visão original é que mostre um <div> com o erro, no caso de que este exista, e estabelecer o valor do atributo value do campo login ao valor do elemento recebido, se existe. Não lincamos o valor do campo password porque, por norma geral, quando há um erro se obriga sempre a voltar a entrar o password.

E pronto! Se o usuário envia um formulário com o campo login ou password vazios, serão mostrados a ele de novo os dados que havia entrado (salvo o password) junto com a mensagem de erro. Simples, verdade? Pois bem, a maneira como fizemos a validação, e a forma como modificamos a visão para mostrar os dados retornados pelo controlador, embora funcionem não são as ideais. Nos próximos artigos veremos duas maneiras mais elegantes de fazê-lo: por um lado a validação mediante Data Annotations e por outro o uso dos helpers nas visões...

Saudações!





Comentários do artigo
Foram enviados 13 comentários ao artigo
13 comentários não revisados
0 comentários revisados

Usuários :    login / registro

Manuais relacionados
Categorias relacionadas
O autor

Home | Sobre nós | Copyright | Anuncie | Entrar em contato