Validando a entrada do usuário em sites do Páginas da Web do ASP.NET (Razor)

por Tom FitzMacken

Este artigo discute como validar as informações que você obtém dos usuários, ou seja, para garantir que os usuários insiram informações válidas em formulários HTML em um site do Páginas da Web do ASP.NET (Razor).

O que você aprenderá:

  • Como marcar que a entrada de um usuário corresponde aos critérios de validação definidos por você.
  • Como determinar se todos os testes de validação foram aprovados.
  • Como exibir erros de validação (e como formatá-los).
  • Como validar dados que não vêm diretamente dos usuários.

Estes são os conceitos de programação ASP.NET introduzidos no artigo:

  • O Validation auxiliar.
  • Os métodos Html.ValidationSummary e Html.ValidationMessage.

Versões de software usadas no tutorial

  • Páginas da Web do ASP.NET (Razor) 3

Este tutorial também funciona com Páginas da Web do ASP.NET 2.

Este artigo inclui as seções a seguir:

Visão geral da validação de entrada do usuário

Se você solicitar que os usuários insiram informações em uma página , por exemplo, em um formulário , é importante garantir que os valores inseridos sejam válidos. Por exemplo, você não deseja processar um formulário que não tem informações críticas.

Quando os usuários inserem valores em um formulário HTML, os valores inseridos são cadeias de caracteres. Em muitos casos, os valores necessários são alguns outros tipos de dados, como inteiros ou datas. Portanto, você também precisa garantir que os valores inseridos pelos usuários possam ser convertidos corretamente nos tipos de dados apropriados.

Você também pode ter determinadas restrições sobre os valores. Mesmo que os usuários insiram corretamente um inteiro, por exemplo, talvez seja necessário verificar se o valor está dentro de um determinado intervalo.

Captura de tela que mostra erros de validação que usam classes de estilo CSS.

Observação

Importante Validar a entrada do usuário também é importante para a segurança. Quando você restringe os valores que os usuários podem inserir em formulários, você reduz a chance de alguém inserir um valor que possa comprometer a segurança do seu site.

Validando entradas de usuário

No Páginas da Web do ASP.NET 2, você pode usar o Validator auxiliar para testar a entrada do usuário. A abordagem básica é fazer o seguinte:

  1. Determine quais elementos de entrada (campos) você deseja validar.

    Normalmente, você valida valores em <input> elementos em um formulário. No entanto, é uma boa prática validar todas as entradas, até mesmo entradas provenientes de um elemento restrito como uma <select> lista. Isso ajuda a garantir que os usuários não ignorem os controles em uma página e enviem um formulário.

  2. No código da página, adicione verificações de validação individuais para cada elemento de entrada usando métodos do Validation auxiliar.

    Para marcar para campos necessários, use Validation.RequireField(field, [error message]) (para um campo individual) ou Validation.RequireFields(field1, field2, ...)) (para uma lista de campos). Para outros tipos de validação, use Validation.Add(field, ValidationType). Para ValidationType, você pode usar estas opções:

    Validator.DateTime ([error message])
    Validator.Decimal([error message])
    Validator.EqualsTo(otherField [, error message])
    Validator.Float([error message])
    Validator.Integer([error message])
    Validator.Range(min, max [, error message])
    Validator.RegEx(pattern [, error message])
    Validator.Required([error message])
    Validator.StringLength(length)
    Validator.Url([error message])

  3. Quando a página é enviada, marcar se a validação foi aprovada verificando Validation.IsValid:

    if(IsPost && Validation.IsValid()){
        // Process form submit
    }
    

    Se houver erros de validação, ignore o processamento de página normal. Por exemplo, se a finalidade da página for atualizar um banco de dados, você não fará isso até que todos os erros de validação tenham sido corrigidos.

  4. Se houver erros de validação, exiba mensagens de erro na marcação da página usando Html.ValidationSummary ou Html.ValidationMessageou ambos.

O exemplo a seguir mostra uma página que ilustra essas etapas.

@{
    var message="";
    // Specify validation requirements for different fields.
    Validation.RequireField("coursename", "Class name is required");
    Validation.RequireField("credits", "Credits is required");
    Validation.Add("coursename", Validator.StringLength(5));
    Validation.Add("credits", Validator.Integer("Credits must be an integer"));
    Validation.Add("credits", Validator.Range(1, 5, "Credits must be between 1 and 5"));
    Validation.Add("startDate", Validator.DateTime("Start date must be a date"));

    if (IsPost)  {
        // Before processing anything, make sure that all user input is valid.
        if (Validation.IsValid()) {
            var coursename = Request["coursename"];
            var credits = Request["credits"].AsInt();
            var startDate = Request["startDate"].AsDateTime();
            message += @"For Class, you entered " + coursename;
            message += @"<br/>For Credits, you entered " + credits.ToString();
            message += @"<br/>For Start Date, you entered " + startDate.ToString("dd-MMM-yyyy");

            // Further processing here
        }
    }
}
<!DOCTYPE html>
<html lang="en">
<head>
  <title>Validation Example</title>
  <style>
      body {margin: 1in; font-family: 'Segoe UI'; font-size: 11pt; }
   </style>
</head>
<body>
  <h1>Validation Example</h1>
  <p>This example page asks the user to enter information about some classes at school.</p>
  <form method="post">
    @Html.ValidationSummary()
    <div>
      <label for="coursename">Course name: </label>
      <input type="text"
         name="coursename"
         value="@Request["coursename"]"
      />
      @Html.ValidationMessage("coursename")
    </div>

    <div>
      <label for="credits">Credits: </label>
      <input type="text"
         name="credits"
         value="@Request["credits"]"
      />
      @Html.ValidationMessage("credits")
    </div>

    <div>
      <label for="startDate">Start date: </label>
      <input type="text"
         name="startDate"
         value="@Request["startDate"]"
      />
      @Html.ValidationMessage("startDate")
    </div>

   <div>
      <input type="submit" value="Submit" class="submit" />
    </div>

    <div>
      @if(IsPost){
        <p>@Html.Raw(message)</p>
      }
    </div>
  </form>
</body>
</html>

Para ver como a validação funciona, execute esta página e cometa erros deliberadamente. Por exemplo, esta é a aparência da página se você esquecer de inserir um nome de curso, se você inserir um e se inserir uma data inválida:

Erros de validação na página renderizada

Adicionando validação de Client-Side

Por padrão, a entrada do usuário é validada depois que os usuários enviam a página , ou seja, a validação é executada no código do servidor. Uma desvantagem dessa abordagem é que os usuários não sabem que cometeram um erro até depois de enviarem a página. Se um formulário for longo ou complexo, relatar erros somente depois que a página for enviada poderá ser inconveniente para o usuário.

Você pode adicionar suporte para executar a validação no script do cliente. Nesse caso, a validação é executada à medida que os usuários trabalham no navegador. Por exemplo, suponha que você especifique que um valor deve ser um inteiro. Se um usuário inserir um valor não inteiro, o erro será relatado assim que o usuário sair do campo de entrada. Os usuários recebem comentários imediatos, o que é conveniente para eles. A validação baseada no cliente também pode reduzir o número de vezes que o usuário precisa enviar o formulário para corrigir vários erros.

Observação

Mesmo que você use a validação do lado do cliente, a validação sempre será executada no código do servidor. A execução da validação no código do servidor é uma medida de segurança, caso os usuários ignorem a validação baseada em cliente.

  1. Registre as seguintes bibliotecas JavaScript na página:

    <script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.2.js">
    </script>
    <script
    src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.8.1/jquery.validate.js">
    </script>
    <script src="~/Scripts/jquery.validate.unobtrusive.js">
    </script>
    

    Duas das bibliotecas podem ser carregadas de uma CDN (rede de distribuição de conteúdo), portanto, você não precisa necessariamente tê-las em seu computador ou servidor. No entanto, você deve ter uma cópia local de jquery.validate.unobtrusive.js. Se você ainda não estiver trabalhando com um modelo do WebMatrix (como o Site Inicial ) que inclui a biblioteca, crie um site de Páginas da Web baseado no Site Inicial. Em seguida, copie o arquivo .js para o site atual.

  2. Na marcação, para cada elemento que você está validando, adicione uma chamada a Validation.For(field). Esse método emite atributos que são usados pela validação do lado do cliente. (Em vez de emitir código JavaScript real, o método emite atributos como data-val-.... Esses atributos dão suporte à validação de cliente não discreta que usa jQuery para fazer o trabalho.)

A página a seguir mostra como adicionar recursos de validação de cliente ao exemplo mostrado anteriormente.

@{
    // Note that client validation as implemented here will work only with
    // ASP.NET Web Pages 2.

    var message="";
    // Specify validation requirements for different fields.
    Validation.RequireField("coursename", "Class name is required");
    Validation.RequireField("credits", "Credits is required");
    Validation.Add("coursename", Validator.StringLength(5));
    Validation.Add("credits", Validator.Integer("Credits must be an integer"));
    Validation.Add("credits", Validator.Range(1, 5, "Credits must be between 1 and 5"));
    Validation.Add("startDate", Validator.DateTime("Start date must be a date"));

    if (IsPost)  {
        // Before processing anything, make sure that all user input is valid.
        if (Validation.IsValid()) {
            var coursename = Request["coursename"];
            var credits = Request["credits"].AsInt();
            var startDate = Request["startDate"].AsDateTime();
            message += @"For Class, you entered " + coursename;
            message += @"<br/>For Credits, you entered " + credits.ToString();
            message += @"<br/>For Start Date, you entered " + startDate.ToString("dd-MMM-yyyy");

            // Further processing here
        }
    }
}
<!DOCTYPE html>
<html lang="en">
<head>
  <title>Validation Example with Client Validation</title>
  <style>
      body {margin: 1in; font-family: 'Segoe UI'; font-size: 11pt; }
   </style>
    <script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.2.js"></script>
    <script
        src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.8.1/jquery.validate.js">
    </script>
    <script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
</head>
<body>
  <h1>Validation Example with Client Validation</h1>
  <p>This example page asks the user to enter information about some classes at school.</p>
  <form method="post">
    @Html.ValidationSummary()
    <div>
      <label for="coursename">Course name: </label>
      <input type="text"
         name="coursename"
         value="@Request["coursename"]"
         @Validation.For("coursename")
      />
      @Html.ValidationMessage("coursename")
    </div>

    <div>
      <label for="credits">Credits: </label>
      <input type="text"
         name="credits"
         value="@Request["credits"]"
         @Validation.For("credits")
      />
      @Html.ValidationMessage("credits")
    </div>

    <div>
      <label for="startDate">Start date: </label>
      <input type="text"
         name="startDate"
         value="@Request["startDate"]"
         @Validation.For("startDate")
      />
      @Html.ValidationMessage("startDate")
    </div>

   <div>
      <input type="submit" value="Submit" class="submit" />
    </div>

    <div>
      @if(IsPost){
        <p>@Html.Raw(message)</p>
      }
    </div>
  </form>
</body>
</html>

Nem todas as verificações de validação são executadas no cliente. Em particular, a validação de tipo de dados (inteiro, data e assim por diante) não é executada no cliente. As verificações a seguir funcionam no cliente e no servidor:

  • Required
  • Range(minValue, maxValue)
  • StringLength(maxLength[, minLength])
  • Regex(pattern)
  • EqualsTo(otherField)

Neste exemplo, o teste para uma data válida não funcionará no código do cliente. No entanto, o teste será executado no código do servidor.

Erros de validação de formatação

Você pode controlar como os erros de validação são exibidos definindo classes CSS que têm os seguintes nomes reservados:

  • field-validation-error. Define a saída do Html.ValidationMessage método quando ele está exibindo um erro.
  • field-validation-valid. Define a saída do Html.ValidationMessage método quando não há erro.
  • input-validation-error. Define como <input> os elementos são renderizados quando há um erro. (Por exemplo, você pode usar essa classe para definir a cor da tela de fundo de um <elemento de entrada> para uma cor diferente se seu valor for inválido.) Essa classe CSS é usada somente durante a validação do cliente (em Páginas da Web do ASP.NET 2).
  • input-validation-valid. Define a aparência dos <input> elementos quando não há erro.
  • validation-summary-errors. Define a saída do Html.ValidationSummary método que está exibindo uma lista de erros.
  • validation-summary-valid. Define a saída do Html.ValidationSummary método quando não há erro.

<style> O bloco a seguir mostra regras para condições de erro.

<style>
.validation-summary-errors {
  border:2px solid red;
  color:red;
  font-weight:bold;
  margin:6px;
  width:30%;
}

.field-validation-error{
  color:red;
   font-weight:bold;
   background-color:yellow;
}

.input-validation-error{
  color:red;
  font-weight:bold;
  background-color:pink;
}
</style>

Se você incluir esse bloco de estilo nas páginas de exemplo do anterior no artigo, a exibição de erro será semelhante à ilustração a seguir:

Erros de validação que usam classes de estilo CSS

Observação

Se você não estiver usando a validação do cliente no Páginas da Web do ASP.NET 2, as classes CSS para os <input> elementos (input-validation-error e input-validation-valid não terão nenhum efeito.

Exibição de erro estático e dinâmico

As regras CSS vêm em pares, como validation-summary-errors e validation-summary-valid. Esses pares permitem definir regras para ambas as condições: uma condição de erro e uma condição "normal" (não erro). É importante entender que a marcação para a exibição de erro é sempre renderizada, mesmo que não haja erros. Por exemplo, se uma página tiver um Html.ValidationSummary método na marcação, a origem da página conterá a seguinte marcação mesmo quando a página for solicitada pela primeira vez:

<div class="validation-summary-valid" data-valmsg-summary="true"><ul></ul></div>

Em outras palavras, o Html.ValidationSummary método sempre renderiza um <div> elemento e uma lista, mesmo que a lista de erros esteja vazia. Da mesma forma, o Html.ValidationMessage método sempre renderiza um <span> elemento como um espaço reservado para um erro de campo individual, mesmo que não haja erro.

Em algumas situações, exibir uma mensagem de erro pode fazer com que a página seja refluxada e pode fazer com que os elementos na página se movam. As regras CSS que terminam em -valid permitem definir um layout que pode ajudar a evitar esse problema. Por exemplo, você pode definir field-validation-error e field-validation-valid ter o mesmo tamanho fixo. Dessa forma, a área de exibição do campo é estática e não alterará o fluxo de página se uma mensagem de erro for exibida.

Validando dados que não vêm diretamente dos usuários

Às vezes, você precisa validar informações que não vêm diretamente de um formulário HTML. Um exemplo típico é uma página em que um valor é passado em uma cadeia de caracteres de consulta, como no exemplo a seguir:

http://server/myapp/EditClassInformation?classid=1022

Nesse caso, você deseja garantir que o valor passado para a página (aqui, 1022 para o valor de classid) seja válido. Você não pode usar diretamente o Validation auxiliar para executar essa validação. No entanto, você pode usar outros recursos do sistema de validação, como a capacidade de exibir mensagens de erro de validação.

Observação

Importante Sempre valide os valores obtidos de qualquer origem, incluindo valores de campo de formulário, valores de cadeia de caracteres de consulta e valores de cookie. É fácil para as pessoas alterar esses valores (talvez para fins mal-intencionados). Portanto, você deve marcar esses valores para proteger seu aplicativo.

O exemplo a seguir mostra como você pode validar um valor que é passado em uma cadeia de caracteres de consulta. O código testa que o valor não está vazio e que é um inteiro.

if(!IsPost){
    if(!Request.QueryString["classid"].IsEmpty() && Request.QueryString["classid"].IsInt()) {
        // Process the value
    }
    else{
        Validation.AddFormError("No class was selected.");
    }
}

Observe que o teste é executado quando a solicitação não é um envio de formulário (if(!IsPost)). Esse teste passaria na primeira vez em que a página é solicitada, mas não quando a solicitação é um envio de formulário.

Para exibir esse erro, você pode adicionar o erro à lista de erros de validação chamando Validation.AddFormError("message"). Se a página contiver uma chamada para o Html.ValidationSummary método , o erro será exibido lá, assim como um erro de validação de entrada do usuário.

Recursos adicionais

Trabalhando com formulários HTML em sites de Páginas da Web do ASP.NET