Como utilizar validação com Asp.Net MVC    

Olá pessoal!

Hoje vou falar de uma tarefa importante no desenvolvimento de sites: Validação.

Na construção de site nós nunca podemos confiar nas informações que o usuário informa, devemos saber que qualquer pessoa pode errar uma digitação ou esquecer de digitar uma informação qualquer, e por isso é importante saber utilizar Validação nos formulários que criamos.

No Asp.Net MVC existem várias formas de realizar validações, mas hoje vou falar de apenas três:

  • Adicionando informações à propriedade ModelState
  • Utilizando DataAnnotations
  • Utilizando DataAnnotations com JQuery

O processo de validação no Asp.Net MVC ficou muito fácil, eu diria que ficou muito mais fácil que no Asp.Net WebForm, vamos então começar pelo básico:

Validando suas Views com ModelState

A validação no Asp.Net MVC sempre é feita através do estado do modelo (ModelState) recebido na Action de um Controller, o que muda é como esse estado é alterado, pois pode feito manualmente, como faremos agora, ou automaticamente, através de ActionFilter customizado ou automático.

A forma básica é você adicionar manualmente informações de erro no modelo ao ModelState, invocando o método AddModelError(chave,mensagemDeErro).

Vamos aos exemplos! Para começar vou criar meu modelo, bem simples, como em todos os meus outros exemplos: Pessoa

   1:  public class Pessoa
   2:  {
   3:      public string Nome { get; set; }
   4:      public string Email { get; set; }
   5:      public string Telefone { get; set; }
   6:      public int Idade { get; set; }
   7:  }

Naturalmente, para criar uma pessoa no banco de dados, algumas informações devem ser obrigatórias e outras devem seguir algum formato específico, para todos os nossos exemplos usaremos as mesmas validações:

  • O nome é obrigatório.
  • O e-mail é obrigatório.
  • O telefone é obrigatório.
  • O e-mail deve seguir o formatado texto@texto.texto
  • A idade é deve ser maior que 18.
  • O telefone deve seguir o formato ####-####

Vou criar duas Actions de nome Edicao, uma para renderizar a View inicial e outra para persistir os dados, essa segunda terá a responsabilidade de fazer a validação do Modelo, e adicionar os erros ao ModelState. Caso não tenha erro, apenas redirecionará o usuário para a página inicial (persistir em uma base de dados não vem ao caso).

Abaixo segue o código das Actions:

   1:  public ActionResult Edicao()
   2:  {
   3:      return View();
   4:  }
   5:   
   6:  [AcceptVerbs(HttpVerbs.Post)]
   7:  public ActionResult Edicao(Pessoa pessoa)
   8:  {
   9:      //Valida os dados no lado do servidor.
  10:      if(string.IsNullOrEmpty(pessoa.Nome))
  11:      ModelState.AddModelError("Nome","Nome é obrigatório");
  12:      
  13:      if (string.IsNullOrEmpty(pessoa.Email))
  14:      ModelState.AddModelError("Email", "Email é obrigatório");
  15:      else{
  16:      if (!Regex.Match(pessoa.Email,@"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$").Success)
  17:      ModelState.AddModelError("Email", "E-mail inválido.");
  18:      }
  19:   
  20:      if (pessoa.Idade <= 18)
  21:      ModelState.AddModelError("Idade", "Idade deve ser maior que 18.");
  22:   
  23:      if (string.IsNullOrEmpty(pessoa.Telefone))
  24:      ModelState.AddModelError("Telefone", "Telefone é obrigatório.");
  25:      else
  26:      {
  27:      if (!Regex.Match(pessoa.Telefone, @"^\d{4}[-]{1}\d{4}$").Success)
  28:          ModelState.AddModelError("Telefone", "Preencha um telefone no formato ####-####");
  29:   
  30:      }
  31:      //Verifica se algum erro acima falhou.
  32:      if (!ModelState.IsValid)
  33:      {
  34:      return View();
  35:      }
  36:      else
  37:      {
  38:      //Se estive certo só redireciono para a página inicial.
  39:      return Redirect("/");
  40:      }   
  41:  }

O código é bem intuitivo, caso tenha adicionado alguma mensagem de erro, a propriedade IsValid do ModelState retornará false, e o modelo estará inválido, assim eu retorno minha mesma View, que exibirá as mensagens de erros. Minha View fica da seguinte forma:

   1:  <%using(Html.BeginForm()){ %>
   2:  <p>
   3:  <%=Html.LabelFor(Model=>Model.Nome)%>
   4:  <%=Html.TextBoxFor(Model=>Model.Nome)%>
   5:  <%=Html.ValidationMessage("Nome")%>
   6:  </p>
   7:  <p>
   8:  <%=Html.LabelFor(Model=>Model.Email)%>
   9:  <%=Html.TextBoxFor(Model=>Model.Email)%>
  10:  <%=Html.ValidationMessage("Email")%>
  11:  </p>
  12:  <p>
  13:  <%=Html.LabelFor(Model=>Model.Telefone)%>
  14:  <%=Html.TextBoxFor(Model=>Model.Telefone)%>
  15:  <%=Html.ValidationMessage("Telefone")%>
  16:  </p>
  17:  <p>
  18:  <%=Html.LabelFor(Model=>Model.Idade)%>
  19:  <%=Html.TextBoxFor(Model=>Model.Idade)%>
  20:  <%=Html.ValidationMessage("Idade")%>
  21:  </p>
  22:  <p>
  23:  <input type="submit" value="Salvar"/>
  24:  </p>
  25:  <%} %>

Veja que a única novidade da minha View a utilização do HTMLHelper ValidationMessage, passando o nome da chave que eu valido no servidor. Ao executar minha tela, caso passe informações inválidas, terei o seguinte resultado:

image

Ou assim:

image

E a sua validação está pronta para ser usada! Eu poderia utilizar um ValidationSummary, apenas utilizando o helper para isso, da seguinte forma: <%=Html.ValidationSummary()%>.

Vamos à nossa segunda forma de validar nosso modelo.

Validando suas Views com DataAnnotarions

DataAnnotations é uma forma de você adicionar validações ao seu modelo através de atributos, incorporada ao .Net 4. O interessante dessa estratégia é que não está ligada ao Asp.Net MVC, portanto, você pode utilizá-la tanto em Asp.Net, como em qualquer outra tecnologia .Net, como WCF. Isso é muito importante, pois você não precisa repetir validação em diversas partes do código, técnica conhecida como DRY (Don’t Repeat Yourself).

Como a validação é centralizada no modelo, nosso modelo sofrerá uma pequena alteração, assim como nossa Action, pois tiraremos a validação da Action e passaremos para o modelo. Nosso modelo ficará assim:

   1:  public class Pessoa
   2:  {
   3:      [Required(ErrorMessage = "O Nome é obrigatório.")]
   4:      public string Nome { get; set; }
   5:   
   6:      [Required(ErrorMessage = "O E-mail é obrigatório.")]
   7:      [RegularExpression(@"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$", ErrorMessage = "E-mail inválido.")]
   8:      public string Email { get; set; }
   9:   
  10:      [Required(ErrorMessage = "O Telefone é obrigatório.")]
  11:      [RegularExpression(@"^\d{4}[-]{1}\d{4}$", ErrorMessage = "Telefone inválido. Informe ####-####.")]
  12:      public string Telefone { get; set; }
  13:   
  14:      [Range(18, Int16.MaxValue, ErrorMessage = "A idade deve ser maior que 18 anos.")]
  15:      public int Idade { get; set; }
  16:  }

Veja que existem vários tipos de atributos de Validação, e para todos eu posso informar uma mensagem de erro personalizada, através da propriedade ErrorMessage, além de cada um ter propriedades específicas de acordo com o tipo.

Como toda a lógica de validação passou para o modelo, nossa Action ficará bem mais simples:

   1:  [AcceptVerbs(HttpVerbs.Post)]
   2:  public ActionResult Edicao(Pessoa pessoa)
   3:  {
   4:      //O modelo já chega validado
   5:      if (!ModelState.IsValid)
   6:      {
   7:      return View();
   8:      }
   9:      else
  10:      {
  11:      //Se estive certo só redireciono para a página inicial.
  12:      return Redirect("/");
  13:      }
  14:  }

Veja como ficou simples a Action agora, e o resultado nas Views é o mesmo, não mudei nada no meu HTML, apenas adicionei um Summary, para ver que o resultado é o mesmo:

image

E mais uma forma de validação já está funcionando e pronta para publicar!

Mas espera aí! Existe um problema nessas duas formas de validação: Ela são realizadas no servidor. Ou seja, o usuário precisa ser submetido ao servidor para realizar a validação, o que pode prejudicar muito a experiência do usuário, e para isso termos a terceira forma de validação de hoje:

Utilizando DataAnnotations com JQuery para validação no Cliente

O mais interessante da utilização do JQuery com DataAnnotation é o impacto no código do servidor: Nada! Isso mesmo, não tem impacto nenhum no servidor para você adicionar validação no Asp.Net MVC no cliente. Vou fazer a seguinte alteração no HTML:

 

   1:  <% Html.EnableClientValidation();%>
   2:  <%using (Html.BeginForm())
   3:  { %>
   4:  <p>
   5:  <%=Html.LabelFor(Model=>Model.Nome)%>
   6:  <%=Html.TextBoxFor(Model=>Model.Nome)%>
   7:  <%=Html.ValidationMessageFor(Model => Model.Nome)%>
   8:  </p>
   9:  <p>
  10:  <%=Html.LabelFor(Model=>Model.Email)%>
  11:  <%=Html.TextBoxFor(Model=>Model.Email)%>
  12:  <%=Html.ValidationMessageFor(Model => Model.Email)%>
  13:  </p>
  14:  <p>
  15:  <%=Html.LabelFor(Model=>Model.Telefone)%>
  16:  <%=Html.TextBoxFor(Model=>Model.Telefone)%>
  17:  <%=Html.ValidationMessageFor(Model => Model.Telefone)%>
  18:  </p>
  19:  <p>
  20:  <%=Html.LabelFor(Model=>Model.Idade)%>
  21:  <%=Html.TextBoxFor(Model=>Model.Idade)%>
  22:  <%=Html.ValidationMessageFor(Model => Model.Idade)%>
  23:  </p>
  24:  <p>
  25:  <input type="submit" value="Salvar" />
  26:  </p>
  27:  <%} %>

As alterações na view foram pequenas, adicionei o Helper EnableClientValidation e mudei ValidationMessage por ValidationMessageFor, fora isso, foi necessário adicionar referência a alguns arquivos JS (JavaScript), você pode adicionar tanto no seu arquivo de Layout  (Master) ou na própria View. Os arquivos são os seguintes:

 

   1:  <script src="<%=Url.Content("~/Scripts/jquery-1.4.1.min.js")%>" type="text/javascript"></script>
   2:  <script src="<%=Url.Content("~/Scripts/jquery.validate.js")%>" type="text/javascript"></script>
   3:  <script src="<%=Url.Content("~/Scripts/MicrosoftMvcJQueryValidation.js")%>" type="text/javascript"></script>
 

Os arquivos que adicionei são os arquivo do próprio JQuery (a versão desatualizada que vem com o Visual Studio 2010, que você pode mudar para a atual), o plug-in Validate do Jquery e um arquivo fornecido pelo time do Asp.Net para fazer o meio campo entre a validação do Asp.Net com o JQuery de forma totalmente transparente. Esse arquivo pode ser baixado com o Asp.Net MVC Futures, clicando aqui.

O Resultado é o mesmo:

image

E assim sua validação já estará funcionando no cliente. O mais legal dessa abordagem é que você realizará a validação tanto no Cliente como no Servidor, sem repetir uma linha de código (DRY).

No servidor que eu digo não é como no WebForm, onde a validação de um Validator Control também funciona tanto no servidor como no cliente, porque naquele caso, é apenas no servidor Asp.Net, visto que a validação está na página. Nesse caso, a validação está no Modelo, logo, o mesmo código pode ser utilizado em uma classe de negócio, WCF, WWF, etc; sem replicação de código.

Existe uma validação nativa no lado do Cliente no MVC, mas preferi mostrar com o Jquery, porque é possível integrar outros plug-ins com a validação, que podem gerar efeitos bem interessantes à sua página.

Bom, acredito que seja o suficiente para você adicionar validação ao sua página, de forma bem clara sem ter que se esforçar muito.

Abaixo você pode baixar uma solução contendo três projetos, um com cada tipo de validação, para você ver que não existe grandes diferenças entra elas.

Abraços e até o próximo pessoal.

ValidatorsMVC.zip (1,00 mb)

27. fevereiro 2011 06:06 by Frederico B. Emídio | Comments (0) | Permalink

Sobre mim

Minha Imagem

Meu nome é Frederico Batista Emídio, trabalho com desenvolvimento de sistemas profissionalmente a oito anos, porém, já faço sites pessoais a pelo menos dez anos.

Para saber mais clique aqui.

Páginas

Calendário

<<  novembro 2017  >>
seteququsedo
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

Visualizar posts em um Calendário
Sigua @fredemidio

MCP Asp.NET