WebMatrix - Validando formulários


Continuando a série de artigos básicos sobre o WebMatrix vou falar sobre como realizar a validação de formulários.

Abra o WebMatrix e clique em - Site From Template - para criar um novo site a partir de um modelo;

Escolha o modelo Empty Site e informe o nome do site. No exemplo eu dei o nome : ValidaFormulario

Vamos incluir na raiz do site um novo arquivo Cadastro.chstml.

Para isso selecione a guia Files e a seguir no menu clique em New -> New File;

Na janela Choose a File Type , clique no tipo CSHTML e informe o nome Cadastro.cshtml e a seguir no botão OK;

Altere o conteúdo do arquivo conforme o código abaixo:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Cadastro de Funcionário</title>
</head>
<body>
<h1>Cadastro de Funcionário</h1>
<form action="" method="post">
<fieldset>
<legend>Detalhes Pessoais</legend>
<div>
    @Html.Label("Nome: ", "nome")
    @Html.TextBox("nome")
</div>
<div>
    @Html.Label("Sobrenome : ", "sobrenome")
    @Html.TextBox("sobrenome")
</div>
<div>
    @Html.Label("Data de nascimento: ", "nascimento")
    @Html.TextBox("nascimento")
</div>
</fieldset>
<fieldset>
<legend>Detalhes Profissionais</legend>
<div>
@Html.Label("Departamento: ", "departamento")
@{
    var listaDepartamento = new List<SelectListItem>()
    {
        new SelectListItem { Value = "Admin", Text = "Administração" },
        new SelectListItem { Value = "RH", Text = "Recursos Humanos" },
        new SelectListItem { Value = "Contabil", Text = "Contabilidade" },
        new SelectListItem { Value = "Vendas", Text = "Vendas e Marketing" },
    };
}
@Html.DropDownList("departamento", "Não Selecionadao", listaDepartamento)
</div>
<div>
<div>
    @Html.Label("Código Funcionário: ", "funcionarioid")
    @Html.TextBox("funcionarioid", "", new { maxlength = 4 })
</div>
</div>
</fieldset>
<div>
<input type="submit" value="Incluir Funcionário" />
</div>
</form>
</body>
</html>

O código da página Cadastro.cshtml gera o formulário visto ao lado. Vamos incluir no início deste arquivo o código razor abaixo:

@{
  if (IsPost)
  {
     Response.Redirect("Sucesso.cshtml");
  }
}

Se executarmos a página no navegador, podemos ver que um formulário vazio será exibido e se clicarmos sobre no botão - Incluir Funcionario - seremos redirecionados para a página Sucesso.cshtml.

No entanto, não podemos permitir que um formulário vazio seja enviado para processamento, que no momento é perfeitamente possível. Neste exemplo, vamos supor que as informações mínimas que exigimos sobre um empregado novo seja seu nome , seu sobrenome e seu código. Então vamos começar validando apenas essas informações incluindo o código abaixo que tornará essas informações obrigatórias.

No topo da página, vamos adicionar algumas variáveis para armazenar os valores dos campos do nosso formulário. Quando o botão submit for acionado, a página é atualizada e os campos são limpos. Precisamos mostrar os dados apresentados de volta ao usuário no formulário e permitir que o usuário faça correções. Para isso vamos passar essas variáveis para os parâmetros de valor do formulário usando os HTML helpers.

@{
    var nome = "";
    var sobrenome = "";
    var nascimento = DateTime.MinValue;
    var departamento = "";
    var funcionarioid = "";
    
 if (IsPost)
 {
    nome = Request["nome"];
    sobrenome = Request["sobrenome"];
    nascimento = Request["nascimento"].AsDateTime();
    departamento = Request["departamento"];
    funcionarioid = Request["funcionarioid"];
    @*Response.Redirect("Sucesso.cshtml");*@
 }
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Cadastro de Funcionário</title>
</head>
<body>
<h1>Cadastro de Funcionário</h1>
<form action="" method="post">
<fieldset>
<legend>Detalhes Pessoais</legend>
<div>
    @Html.Label("Nome: ", "nome")
    @Html.TextBox("nome", nome)
</div>
<div>
    @Html.Label("Sobrenome : ", "sobrenome")
    @Html.TextBox("sobrenome" ,  sobrenome)
</div>
<div>
    @Html.Label("Data de nascimento: ", "nascimento")
    @Html.TextBox("nascimento",  nascimento.ToShortDateString())
</div>
</fieldset>
<fieldset>
<legend>Detalhes Profissionais</legend>
<div>
@Html.Label("Departamento: ", "departamento")
@{
    var listaDepartamento = new List<SelectListItem>()
    {
        new SelectListItem { Value = "Admin", Text = "Administração" },
        new SelectListItem { Value = "RH", Text = "Recursos Humanos" },
        new SelectListItem { Value = "Contabil", Text = "Contabilidade" },
        new SelectListItem { Value = "Vendas", Text = "Vendas e Marketing" },
    };
}
@Html.DropDownList("departamento", "Não Selecionadao", listaDepartamento, departamento, null)
</div>
<div>
<div>
    @Html.Label("Código Funcionário: ", "funcionarioid")
    @Html.TextBox("funcionarioid", funcionarioid, new { maxlength = 4 })
</div>
</div>
</fieldset>
<div>
<input type="submit" value="Incluir Funcionário" />
</div>
</form>
</body>
</html>

O código destacado em azul foi código incluído. Note que comentamos a linha que redireciona para a página Sucesso.cshtml para podermos testar o código.

Usando ModelState

Agora estamos em posição de realizar a nossa primeira parte da validação, que será verificar se os campos nome, sobrenome e codigo do funcionário não estão vazios.

Se um campo estiver vazio, simplesmente queremos registrar o fato e passar para a próxima parte do processo de validação.

Uma vez que todas as validações foram processadas, então vamos informar todos os erros para o usuário, se isso ocorrer.

Para alcançar isso, vamos usar o objeto ModelState da página para armazenar um dicionário de erros (ModelStateDictionary).

No ASP.NET o model refere-se à entidade representada no seu formulário , que em nosso caso é um funcionario, o objeto ModelState armazena o estado (ou seja, a validade) dos dados armazenados em nosso modelo.

Uma vez que todas as validações estejam completas, podemos interrogar a propriedade ModelState.IsValid para determinar se o formulário contém dados válidos. A propriedade ModelState.IsValid será definida para false se qualquer erro for adicionados à ModelStateDictionary.

Nós adicionamos erros de validação para o ModelStateDictionary usando o método ModelState.AddError, passando uma chave (geralmente correspondente com o nome do controle) e a mensagem de erro relevante.

Vamos então alterar o código Razor do início da página conforme abaixo:

@{
    var nome = "";
    var sobrenome = "";
    var nascimento = DateTime.MinValue;
    var departamento = "";
    var funcionarioid = "";
   
 if (IsPost)
 {
    nome = Request["nome"];
    sobrenome = Request["sobrenome"];
    nascimento = Request["nascimento"].AsDateTime();
    departamento = Request["departamento"];
    funcionarioid = Request["funcionarioid"];

    if (nome.IsEmpty())
    {
        ModelState.AddError("nome", "O campo nome deve ser informado");   
    }
    if (sobrenome.IsEmpty())
    {
        ModelState.AddError("sobrenome", "O sobrenome é obrigatório");   
    }
    if (funcionarioid.IsEmpty())
    {
        ModelState.AddError("funcionariodi", "O código do funcionário é obrigatório");
    }
    if (ModelState.IsValid)
    {
        Response.Redirect("Sucesso.cshtml");
    }
 }
}

Exibindo os resultados da validação

As páginas ASP.NET nos fornecem um par de métodos auxiliares projetados para exibir o feedback de validação aos usuários.

O primeiro destes métodos, Html.ValidationSummary(), exibe uma lista HTML não ordeanda de todas as mensagens de erro de validação realizadas na ModelStateDictionary.

O segundo método, ValidationMessage(), exibe a primeira mensagem de erro encontrada em ModelStateDictionary que corresponde à chave especificada.

Vamos inserir um ValidationSummary na parte superior da página e um ValidationMessage ao lado dos campos do formulário relevantes.

Os helpers de validação também atribuem uma classe CSS para as regiões HTML que eles renderizam.

Os estilos CSS definidos na tag <head> deste exemplo irá ajudar os usuários a identificar o feedback destacando os campos relevantes e as mensagens de erro de validação.

Da mesma forma que os helpers ValidationSummary e ValidationMessage todos os campos do formulário identificados como chaves dentro do ModelStateDictionary também são atribuídos a uma classe CSS que pode ser usada para alterar a aparência das tags relevantes HTML.

Abaixo temos, destacada em azul, no código HTML e os helpers que incluem essas funcionalidades

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Cadastro de Funcionário</title>
  <style>
    /* Estilos de formulário */
    fieldset { margin: 0.5em 0; padding: 0.4em; }
    fieldset div { clear: left; padding: 0.3em 0; }
    fieldset label { float: left; width: 7em; text-align: right; padding-right: 0.4em;}
    legend { text-transform:uppercase; font-weight:bold; }
    /* estilos de Validação */
    .validation-summary-errors { font-weight: bold; color: #FF0000; }
    span.field-validation-error { color: #FF0000; }
    input.field-validation-error { border: 1px solid #FF0000; background-color: #FFCCCC; }
  </style>
</head>
<body>
<h1>Cadastro de Funcionário</h1>
    @Html.ValidationSummary("Corrija os seguintes erros :")
<form action="" method="post">
<fieldset>
<legend>Detalhes Pessoais</legend>
<div>
    @Html.Label("Nome: ", "nome")
    @Html.TextBox("nome", nome)
    @Html.ValidationMessage("nome")
</div>
<div>
    @Html.Label("Sobrenome : ", "sobrenome")
    @Html.TextBox("sobrenome" ,  sobrenome)
    @Html.ValidationMessage("sobrenome")
</div>
<div>
    @Html.Label("Data de nascimento: ", "nascimento")
    @Html.TextBox("nascimento",  nascimento.ToShortDateString())
</div>
</fieldset>
<fieldset>
<legend>Detalhes Profissionais</legend>
<div>
@Html.Label("Departamento: ", "departamento")
@{
    var listaDepartamento = new List<SelectListItem>()
    {
        new SelectListItem { Value = "Admin", Text = "Administração" },
        new SelectListItem { Value = "RH", Text = "Recursos Humanos" },
        new SelectListItem { Value = "Contabil", Text = "Contabilidade" },
        new SelectListItem { Value = "Vendas", Text = "Vendas e Marketing" },
    };
}
@Html.DropDownList("departamento", "Não Selecionadao", listaDepartamento, departamento, null)
</div>
<div>
<div>
    @Html.Label("Código Funcionário: ", "funcionarioid")
    @Html.TextBox("funcionarioid", funcionarioid, new { maxlength = 4 })
    @Html.ValidationMessage("funcionarioid")
</div>
</div>
</fieldset>
<div>
<input type="submit" value="Incluir Funcionário" />
</div>
</form>
</body>
</html>

Agora sim temos a implementação da validação definida completa e ao executarmos e tentarmos submeter o formulário incompleto teremos o seguinte resultado:

Pegue o projeto completo aqui: ValidaFormulario.zip

Rom 8:19 Porque a criação aguarda com ardente expectativa a revelação dos filhos de Deus.

Rom 8:20 Porquanto a criação ficou sujeita à vaidade, não por sua vontade, mas por causa daquele que a sujeitou,

Rom 8:21 na esperança de que também a própria criação há de ser liberta do cativeiro da corrupção, para a liberdade da glória dos filhos de Deus.

Referências:


José Carlos Macoratti