ASP .NET MVC - Desmistificando o ModelState (Conceito)


 No artigo de hoje vou apresentar o ModelState da ASP .NET MVC apresentando os conceitos básicos desse importante recurso.

O que é o ModelState ?

O ModeState é uma propriedade da classe Controller e pode ser acessada a partir das classe que herdam de System.Web.Mvc.Controller.

Ele representa uma coleção de pares nome/valor que são submetidos ao servidor durante o POST e também contém uma coleção de mensagens de erros para cada valor submetido.

Apesar do seu nome o ModelState não tem conhecimento das classes do Model, ele possui apenas nomes, valores e erros.

Pra quê serve o ModelState ?

O ModelState possui dois propósitos :

  1. Armazenar o valor submetido ao servidor;
  2. Armazenar os erros de validações associados com esses valores;

Vejamos um exemplo prático para que fique bem claro como esse recurso funciona.

Recursos usados :

Criando o projeto no VS 2013 Express for web

Abra o VS 2013 Express for web e clique em New Project;

A seguir selecione Visual C# -> ASP .NET Web Application;

Informe o nome Mvc_ModelState e clique no botão OK;

A seguir selecione o template Empty, marque MVC  e clique no botão OK;

Será criado um projeto ASP .NET MVC vazio com a estrutura básica para criarmos o nosso exemplo.

Definindo o Model : criando aclasse Usuario na pasta Models

Precisamos agora definir um model para que nossa aplicação possa ter o que consumir. Neste exemplo eu vou criar uma classe Produto com uma estrutura bem simples para simular um cenário de uma loja virtual.

Selecione a pasta Models e no menu PROJECT clique em Add Class e informe o nome Usuario e a seguir clique no botão Add:

A seguir digite o código abaixo definindo 3 propriedades na classe Usuario:

Observe que definimos o namespace System.Componente.DataAnnotations para poder aplicar os atributos de validação : Required, StringLength e Display ao nosso modelo e assim realizar a validação do formulário quando do envio dos dados ao servidor.

Criando o controlador HomeController na pasta Controllers

Clique com o botão direito do mouse sobre a pasta Controllers e a seguir clique em Add => Controller;

A seguir selecione o Scaffold : MVC 5 Controller Empty e clique no botão Add;

Digite o nome HomeController na janela Add Controller e clique no botão Add:

Digite o código abaixo para o HomeController:

Temos definidos no controlador HomeController e Actions:

Estamos definindo uma validação que inclui no ModelState uma mensagem de erro usando o método AddModelError() quando o nome for igual ao sobrenome.

A sintaxe do método AddModelError é : AddModelError(chave,mensagemDeErro)

A seguir verificamos se o modelo é válido usando o método IsValid do ModelState.

Se o modelo NÃO for válido então apresentamos novamente o model no formulário com os erros, caso contrário redirecionamos para a Action Index.

Criando as views - Criando as views Index e Incluir na pasta Views/Home

1- Criando a view Index

Para criar as views o procedimento é clicar com o botão direito sobre o nome do método Action Index no controlador e a seguir clique em Add View:

Para a view Index selecione o template Empty (without model) e clique no botão Add;

Será criado o arquivo Index.cshtml na pasta Views/Home.

A seguir inclua o código abaixo neste arquivo:

@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
    <div>
        <h2>Macoratti .net - Usando ModelState</h2>
        <hr />
        @Html.ActionLink("Incluir um usuário", "Incluir")
    </div>
</body>
</html>

Nesta view estamos usando o HTML Helper ActionLink para criar um link na página com o texto "Incluir um usuário" que quando acionado irá executar a Action Incluir do controlador HomeController.

Sintaxe do ActionLink:  @Html.ActionLink("texto do link", " Nome da Action")

2- Criando a view Incluir

Agora clique com o botão direito sobre o nome do método Action Incluir no controlador e a seguir clique em Add View:

A seguir defina o nome Incluir e o template Empty;

Selecione o Model class Usuario contido na pasta Models e clique no botão Add;

Vamos criar uma view tipada usando o model Usuario. Para isso inclua o código abaixo no arquivo Incluir.cshtml da pasta Views/Home:

@model Mvc_ModelState.Models.Usuario
@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Incluir</title>
</head>
<body>
<h2>Cadastro de Usuário</h2>
@using (Html.BeginForm())
{
    @Html.ValidationSummary()
    <div>
        <div>
            @Html.LabelFor(x => x.Nome)
            @Html.TextBoxFor(x => x.Nome)
            @Html.ValidationMessageFor(x => x.Nome)
        </div>
        <div>
            @Html.LabelFor(x => x.SobreNome)
            @Html.TextBoxFor(x => x.SobreNome)
            @Html.ValidationMessageFor(x => x.SobreNome)
        </div>
        <div>
            @Html.LabelFor(x => x.Email)
            @Html.TextBoxFor(x => x.Email)
            @Html.ValidationMessageFor(x => x.Email)
        </div>
        <div>
            <input type="submit" value="Salvar" />
        </div>
    </div>
}
</body>
</html>

Observe a diretiva @model no início do código definindo um tipo específico que esta view irá renderizar.

Usamos também os html Helpers LabelFor, TextBoxFor para exibir os dados do usuário,e ValidationmessageFor para exibir a mensagem de erro de uma propriedade do específica do Model e ValidatonSummary para exibir as mensagens de erro do Model.

Nota : No ASP .NET MVC a validação e verificação das informações são realizadas por meio de atributos, quando ocorre uma mensagem de erro os métodos ValidationSummary, ValidationMessage e ValidationMessageFor são usados para exibir a mensagem ao usuário.

O MVC detecta os atributos de validação e os utiliza para validar os dados durante o processo model binding. Lembre-se que temos que declarar o namespace System.ComponentModel.DataAnnotations.

Executando o projeto iremos obter a view Index.cshtml com o link para a Action Incluir que aciona a view Incluir.cshtml:

Ao postar os dados do formulário clicando no botão Salvar todos os valores nas tags <input> serão submetidas ao servidor como pares chave/valor.

Quando o MVC recebe o POST ele toma todos os parâmetros postados e os adiciona para uma instância de ModelStateDictionary.

Fazendo o Debug do controller durante a ação de POST podemos espiar o conteúdo de ModelState:

Os valores da propriedade de ModelStateDictionary contém instâncias que são do tipo System.Web.Mvc.ModelState.

Expandindo para visualizar o conteúdo do ModelState atual obtemos:

Note que cada propriedade tem uma instância de ValueProviderResult que contém os valores atuais submetidos ao servidor.

O MVC cria todas estas instâncias automaticamente para nós quando submetemos um POST com dados e a Action POST possui entradas que mapeam para os valores submetidos. Essencialmente o MVC esta encapsulando a entrada do usuário em classes no servidor (ModelState e ValueProviderResult) para facilitar o seu uso.

A propriedade ModelState.Errors e a propriedade ModelStateDictionary.IsValid são usadas para executar o segundo propósito do ModelState: armazenar os erros encontrados nos valores submetidos.

Observe que a instância ModelState para o sobrenome e email agora possui um erro na coleção Errors.

Quando o MVC cria um model state para as propriedades submetidas ele percorre cada propriedade no Model e faz a validação da propriedade usando os atributos associados a ela.

Se qualquer erro for encontrado eles são adicionados na coleção Errors da propriedade ModelState.

Note também que a propriedade IsValid agora é false porque existe um erro no modelo. IsValid será false se qualquer propriedade submetida tiver uma mensagem de erro anexada a ela.

Concluímos então que configurando e usando a validação desta maneira permitimos que o MVC trabalhe da forma correta onde ModelState armazena os valores submetidos permitindo que eles sejam mapeados para propriedades de classes ou apenas como parâmetros da action e mantenha uma coleção de  mensagens de erros para cada propriedade.

Pegue o projeto completo aqui : Mvc_ModelState.zip

Jesus lhes respondeu, e disse: A minha doutrina não é minha, mas daquele que me enviou.
Se alguém quiser fazer a vontade dele, pela mesma doutrina conhecerá se ela é de Deus, ou se eu falo de mim mesmo.
João 7:16,17

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

  Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter

Referências:


José Carlos Macoratti