Parte 8 da série de tutoriais em Razor páginas.Part 8 of tutorial series on Razor Pages.

De Rick AndersonBy Rick Anderson

Nesta seção, a lógica de validação é adicionada para o modelo Movie.In this section, validation logic is added to the Movie model. As regras de validação são impostas sempre que um usuário cria ou edita um filme.The validation rules are enforced any time a user creates or edits a movie.

ValidaçãoValidation

Um princípio-chave do desenvolvimento de software é chamado DRY (“D on't R epeat Y ourself”).A key tenet of software development is called DRY ("D on't R epeat Y ourself"). Razor As páginas incentivam o desenvolvimento onde a funcionalidade é especificada uma vez e é refletida em todo o aplicativo.Razor Pages encourages development where functionality is specified once, and it's reflected throughout the app. O DRY pode ajudar a:DRY can help:

  • Reduzir a quantidade de código em um aplicativo.Reduce the amount of code in an app.
  • Fazer com que o código seja menos propenso a erros e mais fácil de ser testado e mantido.Make the code less error prone, and easier to test and maintain.

O suporte de validação fornecido por Razor páginas e Entity Framework é um bom exemplo do princípio seco:The validation support provided by Razor Pages and Entity Framework is a good example of the DRY principle:

  • As regras de validação são especificadas declarativamente em um único lugar, na classe de modelo.Validation rules are declaratively specified in one place, in the model class.
  • As regras são impostas em todos os lugares no aplicativo.Rules are enforced everywhere in the app.

Adicionar regras de validação ao modelo de filmeAdd validation rules to the movie model

O DataAnnotations namespace fornece:The DataAnnotations namespace provides:

  • Um conjunto de atributos de validação internos que são aplicados declarativamente a uma classe ou propriedade.A set of built-in validation attributes that are applied declaratively to a class or property.
  • Formatação de atributos como [DataType] essa ajuda com a formatação e não fornecem nenhuma validação.Formatting attributes like [DataType] that help with formatting and don't provide any validation.

Atualize a classe Movie para aproveitar os atributos de validação [Required], [StringLength], [RegularExpression] e [Range] internos.Update the Movie class to take advantage of the built-in [Required], [StringLength], [RegularExpression], and [Range] validation attributes.

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace RazorPagesMovie.Models
{
    public class Movie
    {
        public int ID { get; set; }

        [StringLength(60, MinimumLength = 3)]
        [Required]
        public string Title { get; set; }

        [Display(Name = "Release Date")]
        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }

        [Range(1, 100)]
        [DataType(DataType.Currency)]
        [Column(TypeName = "decimal(18, 2)")]
        public decimal Price { get; set; }

        [RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$")]
        [Required]
        [StringLength(30)]
        public string Genre { get; set; }

        [RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$")]
        [StringLength(5)]
        [Required]
        public string Rating { get; set; }
    }

Os atributos de validação especificam o comportamento a ser aplicado nas propriedades de modelo às quais eles são aplicados:The validation attributes specify behavior to enforce on the model properties they're applied to:

  • Os atributos [Required] e [MinimumLength] indicam que uma propriedade deve ter um valor.The [Required] and [MinimumLength] attributes indicate that a property must have a value. Nada impede que um usuário insira espaço em branco para atender a essa validação.Nothing prevents a user from entering white space to satisfy this validation.

  • O atributo [RegularExpression] é usado para limitar quais caracteres podem ser inseridos.The [RegularExpression] attribute is used to limit what characters can be input. No código anterior, Genre :In the preceding code, Genre:

    • Deve usar apenas letras.Must only use letters.
    • A primeira letra deve ser maiúscula.The first letter is required to be uppercase. Espaços em branco são permitidos enquanto números e caracteres especiais não são permitidos.White spaces are allowed while numbers, and special characters are not allowed.
  • O RegularExpression Rating :The RegularExpression Rating:

    • Exige que o primeiro caractere seja uma letra maiúscula.Requires that the first character be an uppercase letter.
    • Permite caracteres especiais e números em espaços subsequentes.Allows special characters and numbers in subsequent spaces. "PG-13" é válido para uma classificação, mas falha para um Genre ."PG-13" is valid for a rating, but fails for a Genre.
  • O atributo [Range] restringe um valor a um intervalo especificado.The [Range] attribute constrains a value to within a specified range.

  • O [StringLength] atributo pode definir um comprimento máximo de uma propriedade de cadeia de caracteres e, opcionalmente, seu comprimento mínimo.The [StringLength] attribute can set a maximum length of a string property, and optionally its minimum length.

  • Tipos de valor, como decimal ,,, int float DateTime , são inerentemente necessários e não precisam do [Required] atributo.Value types, such as decimal, int, float, DateTime, are inherently required and don't need the [Required] attribute.

As regras de validação anteriores são usadas para demonstração, elas não são ideais para um sistema de produção.The preceding validation rules are used for demonstration, they are not optimal for a production system. Por exemplo, o anterior impede a inserção de um filme com apenas dois caracteres e não permite caracteres especiais no Genre .For example, the preceding prevents entering a movie with only two chars and doesn't allow special characters in Genre.

Ter regras de validação automaticamente impostas pelo ASP.NET Core ajuda a:Having validation rules automatically enforced by ASP.NET Core helps:

  • Ajuda a tornar o aplicativo mais robusto.Helps make the app more robust.
  • Reduza as chances de salvar dados inválidos no banco de dado.Reduce chances of saving invalid data to the database.

IU de erro de validação em Razor páginasValidation Error UI in Razor Pages

Execute o aplicativo e navegue para Pages/Movies.Run the app and navigate to Pages/Movies.

Selecione o link Criar Novo.Select the Create New link. Preencha o formulário com alguns valores inválidos.Complete the form with some invalid values. Quando a validação do lado do cliente do jQuery detecta o erro, ela exibe uma mensagem de erro.When jQuery client-side validation detects the error, it displays an error message.

Formulário da exibição de filmes com vários erros de validação do lado do cliente do jQuery

Observação

Talvez você não consiga inserir vírgulas decimais em campos decimais.You may not be able to enter decimal commas in decimal fields. Para dar suporte à validação do jQuery para localidades de idiomas diferentes do inglês que usam uma vírgula (“,”) para um ponto decimal e formatos de data diferentes do inglês dos EUA, você deve tomar medidas para globalizar o aplicativo.To support jQuery validation for non-English locales that use a comma (",") for a decimal point, and non US-English date formats, you must take steps to globalize your app. Consulte este problema do GitHub 4076 para obter instruções sobre como adicionar vírgula decimal.See this GitHub issue 4076 for instructions on adding decimal comma.

Observe como o formulário renderizou automaticamente uma mensagem de erro de validação em cada campo que contém um valor inválido.Notice how the form has automatically rendered a validation error message in each field containing an invalid value. Os erros são impostos no lado do cliente, usando JavaScript e jQuery, e no lado do servidor, quando um usuário tem o JavaScript desabilitado.The errors are enforced both client-side, using JavaScript and jQuery, and server-side, when a user has JavaScript disabled.

Um benefício significativo é que nenhuma alteração de código foi necessária nas páginas criar ou editar.A significant benefit is that no code changes were necessary in the Create or Edit pages. Depois que as anotações de dados forem aplicadas ao modelo, a interface do usuário de validação foi habilitada.Once data annotations were applied to the model, the validation UI was enabled. As Razor páginas criadas neste tutorial captam automaticamente as regras de validação, usando atributos de validação nas propriedades da Movie classe de modelo.The Razor Pages created in this tutorial automatically picked up the validation rules, using validation attributes on the properties of the Movie model class. Validação do teste usando a página Editar: a mesma validação é aplicada.Test validation using the Edit page, the same validation is applied.

Os dados de formulário não serão postados no servidor enquanto houver erros de validação do lado do cliente.The form data isn't posted to the server until there are no client-side validation errors. Verifique se os dados de formulário não são postados por uma ou mais das seguintes abordagens:Verify form data isn't posted by one or more of the following approaches:

  • Coloque um ponto de interrupção no método OnPostAsync.Put a break point in the OnPostAsync method. Envie o formulário selecionando criar ou salvar.Submit the form by selecting Create or Save. O ponto de interrupção nunca é atingido.The break point is never hit.
  • Use a ferramenta Fiddler.Use the Fiddler tool.
  • Use as ferramentas do desenvolvedor do navegador para monitorar o tráfego de rede.Use the browser developer tools to monitor network traffic.

Validação do servidorServer-side validation

Quando o JavaScript está desabilitado no navegador, o envio do formulário com erros será postado no servidor.When JavaScript is disabled in the browser, submitting the form with errors will post to the server.

(Opcional) Teste a validação do servidor:Optional, test server-side validation:

  1. Desabilite o JavaScript no navegador.Disable JavaScript in the browser. O JavaScript pode ser desabilitado usando as ferramentas de desenvolvedor do navegador.JavaScript can be disabled using browser's developer tools. Se o JavaScript não puder ser desabilitado no navegador, tente outro navegador.If JavaScript cannot be disabled in the browser, try another browser.

  2. Defina um ponto de interrupção no método OnPostAsync da página Criar ou Editar.Set a break point in the OnPostAsync method of the Create or Edit page.

  3. Envie um formulário com dados inválidos.Submit a form with invalid data.

  4. Verifique se o estado do modelo é inválido:Verify the model state is invalid:

     if (!ModelState.IsValid)
     {
        return Page();
     }
    

Como alternativa, desabilite a validação do lado do cliente no servidor.Alternatively, Disable client-side validation on the server.

O código a seguir mostra uma parte da página Create.cshtml gerada anteriormente com scaffold no tutorial.The following code shows a portion of the Create.cshtml page scaffolded earlier in the tutorial. Ele é usado pelas páginas criar e editar para:It's used by the Create and Edit pages to:

  • Exibir o formulário inicial.Display the initial form.
  • Reexiba o formulário no caso de um erro.Redisplay the form in the event of an error.
<form method="post">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    <div class="form-group">
        <label asp-for="Movie.Title" class="control-label"></label>
        <input asp-for="Movie.Title" class="form-control" />
        <span asp-validation-for="Movie.Title" class="text-danger"></span>
    </div>

O Auxiliar de Marcação de Entrada usa os atributos de DataAnnotations e produz os atributos HTML necessários para a Validação do jQuery no lado do cliente.The Input Tag Helper uses the DataAnnotations attributes and produces HTML attributes needed for jQuery Validation on the client-side. O Auxiliar de Marcação de Validação exibe erros de validação.The Validation Tag Helper displays validation errors. Consulte Validação para obter mais informações.See Validation for more information.

As páginas Criar e Editar não têm nenhuma regra de validação.The Create and Edit pages have no validation rules in them. As regras de validação e as cadeias de caracteres de erro são especificadas somente na classe Movie.The validation rules and the error strings are specified only in the Movie class. Essas regras de validação são aplicadas automaticamente a Razor páginas que editam o Movie modelo.These validation rules are automatically applied to Razor Pages that edit the Movie model.

Quando a lógica de validação precisa ser alterada, ela é feita apenas no modelo.When validation logic needs to change, it's done only in the model. A validação é aplicada consistentemente em todo o aplicativo, a lógica de validação é definida em um único local.Validation is applied consistently throughout the application, validation logic is defined in one place. A validação em um único lugar ajuda a manter o código limpo e facilita sua manutenção e atualização.Validation in one place helps keep the code clean, and makes it easier to maintain and update.

Usar atributos de tipo de dadosUse DataType Attributes

Examine a classe Movie.Examine the Movie class. O namespace System.ComponentModel.DataAnnotations fornece atributos de formatação, além do conjunto interno de atributos de validação.The System.ComponentModel.DataAnnotations namespace provides formatting attributes in addition to the built-in set of validation attributes. O atributo [DataType] é aplicado às propriedades ReleaseDate e Price.The [DataType] attribute is applied to the ReleaseDate and Price properties.

[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }

[Range(1, 100)]
[DataType(DataType.Currency)]
public decimal Price { get; set; }

Os [DataType] atributos fornecem:The [DataType] attributes provide:

  • Dicas para que o mecanismo de exibição formate os dados.Hints for the view engine to format the data.
  • Fornece atributos como <a> para URL e <a href="mailto:EmailAddress.com"> para email.Supplies attributes such as <a> for URL's and <a href="mailto:EmailAddress.com"> for email.

Use o atributo [RegularExpression] para validar o formato dos dados.Use the [RegularExpression] attribute to validate the format of the data. O atributo [DataType] é usado para especificar um tipo de dados mais específico do que o tipo intrínseco de banco de dados.The [DataType] attribute is used to specify a data type that's more specific than the database intrinsic type. [DataType] atributos não são atributos de validação.[DataType] attributes aren't validation attributes. No aplicativo de exemplo, apenas a data é exibida, sem a hora.In the sample application, only the date is displayed, without time.

A DataType enumeração fornece muitos tipos de dados, como Date ,,, Time PhoneNumber Currency , EmailAddress e muito mais.The DataType enumeration provides many data types, such as Date, Time, PhoneNumber, Currency, EmailAddress, and more.

Os [DataType] atributos:The [DataType] attributes:

  • Pode permitir que o aplicativo forneça automaticamente recursos específicos de tipo.Can enable the application to automatically provide type-specific features. Por exemplo, um link mailto: pode ser criado para DataType.EmailAddress.For example, a mailto: link can be created for DataType.EmailAddress.
  • Pode fornecer um seletor DataType.Date de data em navegadores que dão suporte a HTML5.Can provide a date selector DataType.Date in browsers that support HTML5.
  • Emitir HTML 5 data- , pronunciado "Dash de dados", atributos que o HTML 5 navegadores consomem.Emit HTML 5 data-, pronounced "data dash", attributes that HTML 5 browsers consume.
  • Não forneça nenhuma validação.Do not provide any validation.

DataType.Date não especifica o formato da data exibida.DataType.Date doesn't specify the format of the date that's displayed. Por padrão, o campo de dados é exibido de acordo com os formatos padrão com base nas CultureInfo do servidor.By default, the data field is displayed according to the default formats based on the server's CultureInfo.

A anotação de dados [Column(TypeName = "decimal(18, 2)")] é necessária para que o Entity Framework Core possa mapear corretamente o Price para a moeda no banco de dados.The [Column(TypeName = "decimal(18, 2)")] data annotation is required so Entity Framework Core can correctly map Price to currency in the database. Para obter mais informações, veja Tipos de Dados.For more information, see Data Types.

O atributo [DisplayFormat] é usado para especificar explicitamente o formato de data:The [DisplayFormat] attribute is used to explicitly specify the date format:

[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }

A ApplyFormatInEditMode configuração especifica que a formatação será aplicada quando o valor for exibido para edição.The ApplyFormatInEditMode setting specifies that the formatting will be applied when the value is displayed for editing. Esse comportamento pode não ser desejado para alguns campos.That behavior may not be wanted for some fields. Por exemplo, em valores de moeda, o símbolo de moeda normalmente não é desejado na interface do usuário de edição.For example, in currency values, the currency symbol is usually not wanted in the edit UI.

O atributo [DisplayFormat] pode ser usado por si só, mas geralmente é uma boa ideia usar o atributo [DataType].The [DisplayFormat] attribute can be used by itself, but it's generally a good idea to use the [DataType] attribute. O atributo [DataType] transmite a semântica dos dados em vez de como renderizá-los em uma tela.The [DataType] attribute conveys the semantics of the data as opposed to how to render it on a screen. O [DataType] atributo fornece os seguintes benefícios que não estão disponíveis com [DisplayFormat] :The [DataType] attribute provides the following benefits that aren't available with [DisplayFormat]:

  • O navegador pode habilitar recursos do HTML5, por exemplo, para mostrar um controle de calendário, o símbolo de moeda apropriado da localidade, links de email, etc.The browser can enable HTML5 features, for example to show a calendar control, the locale-appropriate currency symbol, email links, etc.
  • Por padrão, o navegador renderiza dados usando o formato correto com base em sua localidade.By default, the browser renders data using the correct format based on its locale.
  • O atributo [DataType] pode permitir que a estrutura ASP.NET Core escolha o modelo de campo correto para renderizar os dados.The [DataType] attribute can enable the ASP.NET Core framework to choose the right field template to render the data. O DisplayFormat , se usado por si só, usa o modelo de cadeia de caracteres.The DisplayFormat, if used by itself, uses the string template.

Observação: a validação do jQuery não funciona com o [Range] atributo e DateTime .Note: jQuery validation doesn't work with the [Range] attribute and DateTime. Por exemplo, o seguinte código sempre exibirá um erro de validação do lado do cliente, mesmo quando a data estiver no intervalo especificado:For example, the following code will always display a client-side validation error, even when the date is in the specified range:

[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]

É uma prática recomendada evitar a compilação de datas rígidas em modelos, portanto, usando o [Range] atributo e DateTime não é recomendado.It's a best practice to avoid compiling hard dates in models, so using the [Range] attribute and DateTime is discouraged. Use a configuração para intervalos de datas e outros valores sujeitos a alterações frequentes em vez de especificá-los no código.Use Configuration for date ranges and other values that are subject to frequent change rather than specifying it in code.

O seguinte código mostra como combinar atributos em uma linha:The following code shows combining attributes on one line:

public class Movie
{
    public int ID { get; set; }

    [StringLength(60, MinimumLength = 3)]
    public string Title { get; set; }

    [Display(Name = "Release Date"), DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$"), Required, StringLength(30)]
    public string Genre { get; set; }

    [Range(1, 100), DataType(DataType.Currency)]
    [Column(TypeName = "decimal(18, 2)")]
    public decimal Price { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$"), StringLength(5)]
    public string Rating { get; set; }
}

Introdução ao Razor As páginas e EF Core mostram as operações de EF Core avançadas com Razor páginas.Get started with Razor Pages and EF Core shows advanced EF Core operations with Razor Pages.

Aplicar migraçõesApply migrations

As anotações de aplicadas à classe alteram o esquema.The DataAnnotations applied to the class changes the schema. Por exemplo, as DataAnnotations aplicadas ao campo Title:For example, the DataAnnotations applied to the Title field:

[StringLength(60, MinimumLength = 3)]
[Required]
public string Title { get; set; }
  • Limitam os caracteres a 60.Limits the characters to 60.
  • Não permitem um valor null.Doesn't allow a null value.

Atualmente a tabela Movie tem o seguinte esquema:The Movie table currently has the following schema:

CREATE TABLE [dbo].[Movie] (
    [ID]          INT             IDENTITY (1, 1) NOT NULL,
    [Title]       NVARCHAR (MAX)  NULL,
    [ReleaseDate] DATETIME2 (7)   NOT NULL,
    [Genre]       NVARCHAR (MAX)  NULL,
    [Price]       DECIMAL (18, 2) NOT NULL,
    [Rating]      NVARCHAR (MAX)  NULL,
    CONSTRAINT [PK_Movie] PRIMARY KEY CLUSTERED ([ID] ASC)
);

As alterações do esquema anterior não fazem com que o EF lance uma exceção.The preceding schema changes don't cause EF to throw an exception. No entanto, crie uma migração de forma que o esquema seja consistente com o modelo.However, create a migration so the schema is consistent with the model.

No menu Ferramentas, selecione Gerenciador de Pacotes NuGet > Console do Gerenciador de Pacotes.From the Tools menu, select NuGet Package Manager > Package Manager Console. No PMC, insira os seguintes comandos:In the PMC, enter the following commands:

Add-Migration New_DataAnnotations
Update-Database

Update-Database executa os métodos Up da classe New_DataAnnotations.Update-Database runs the Up methods of the New_DataAnnotations class. Examine o método Up:Examine the Up method:

public partial class New_DataAnnotations : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.AlterColumn<string>(
            name: "Title",
            table: "Movie",
            maxLength: 60,
            nullable: false,
            oldClrType: typeof(string),
            oldNullable: true);

        migrationBuilder.AlterColumn<string>(
            name: "Rating",
            table: "Movie",
            maxLength: 5,
            nullable: false,
            oldClrType: typeof(string),
            oldNullable: true);

        migrationBuilder.AlterColumn<string>(
            name: "Genre",
            table: "Movie",
            maxLength: 30,
            nullable: false,
            oldClrType: typeof(string),
            oldNullable: true);
    }

A tabela Movie atualizada tem o seguinte esquema:The updated Movie table has the following schema:

CREATE TABLE [dbo].[Movie] (
    [ID]          INT             IDENTITY (1, 1) NOT NULL,
    [Title]       NVARCHAR (60)   NOT NULL,
    [ReleaseDate] DATETIME2 (7)   NOT NULL,
    [Genre]       NVARCHAR (30)   NOT NULL,
    [Price]       DECIMAL (18, 2) NOT NULL,
    [Rating]      NVARCHAR (5)    NOT NULL,
    CONSTRAINT [PK_Movie] PRIMARY KEY CLUSTERED ([ID] ASC)
);

Publicar no AzurePublish to Azure

Para obter informações sobre como implantar no Azure, consulte tutorial: criar um aplicativo ASP.NET Core no Azure com o banco de dados SQL.For information on deploying to Azure, see Tutorial: Build an ASP.NET Core app in Azure with SQL Database.

Obrigado por concluir esta introdução às Razor páginas.Thanks for completing this introduction to Razor Pages. Introdução ao Razor As páginas e EF Core são um excelente acompanhamento deste tutorial.Get started with Razor Pages and EF Core is an excellent follow up to this tutorial.

Recursos adicionaisAdditional resources