Часть 8 серии руководств по Razor Pages

Примечание.

Это не последняя версия этой статьи. В текущем выпуске см . версию .NET 8 этой статьи.

Внимание

Эта информация относится к предварительному выпуску продукта, который может быть существенно изменен до его коммерческого выпуска. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.

В текущем выпуске см . версию .NET 8 этой статьи.

Автор: Рик Андерсон (Rick Anderson)

В этом разделе к модели Movie добавляется логика проверки. Правила проверки применяются каждый раз, когда пользователь создает или редактирует фильм.

Проверка

Ключевой принцип разработки программного обеспечения называется DRY (от английского "Don't Repeat Yourself" — не повторяйся). При разработке Razor Pages рекомендуется задавать любые функциональные возможности лишь один раз и затем при необходимости отражать их в рамках всего приложения. Принцип "Не повторяйся" может помочь:

  • сократить объем кода в приложении;
  • снизить вероятность возникновения ошибки в коде и упростить его тестирование и поддержку.

Ярким примером применения принципа "Не повторяйся" является поддержка проверки, реализуемая в Razor Pages и на платформе Entity Framework:

  • Правила проверки декларативно определяются в одном месте, в классе модели.
  • Правила применяются по всему приложению.

Добавление правил проверки к модели фильма

Пространство имен System.ComponentModel.DataAnnotations предоставляет:

  • Набор встроенных атрибутов проверки, которые декларативно применяются к классу или свойству.
  • Атрибуты форматирования (такие как [DataType]), которые обеспечивают форматирование и не предназначены для проверки.

Обновите класс Movie, чтобы использовать преимущества встроенных атрибутов проверки [Required], [StringLength], [RegularExpression] и [Range].

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; } = string.Empty;

    [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; } = string.Empty;

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

Атрибуты проверки определяют поведение для свойств модели, к которым они применяются:

  • Атрибуты [Required] и [MinimumLength] означают, что свойство должно иметь значение. Пользователь может свободно вводить пробелы для выполнения этой проверки.

  • Атрибут [RegularExpression] ограничивает набор допустимых для ввода символов. В приведенном выше коде в Genre:

    • должны использоваться только буквы;
    • Первая буква должна быть прописной. Пробелы разрешены, в то время как числа и специальные символы не допускаются.
  • RegularExpressionRating:

    • первый символ должен быть прописной буквой;
    • допускаются специальные символы и цифры, а также последующие пробелы. значение "PG-13" допустимо для рейтинга, но недопустимо для Genre;
  • атрибут [Range] ограничивает значения указанным диапазоном.

  • Атрибут [StringLength] может задавать максимальную и, при необходимости, минимальную длину строкового свойства.

  • Типы значений (например, decimal, int, float, DateTime) по своей природе являются обязательными и не требуют атрибута [Required].

Указанные выше правила проверки используются для демонстрации, они не являются оптимальными для рабочей системы. Например, предыдущее исключение не позволяет ввести модель Movie с двумя символами и не допускает специальные знаки в Genre.

Наличие правил проверки, которые автоматически применяются ASP.NET Core, помогает:

  • сделать приложение более надежным;
  • сократить возможность сохранения недопустимых данных в базе данных.

Пользовательский интерфейс проверки ошибок в Razor Pages

Запустите приложение и перейдите в раздел "Pages/Movies" (Страницы/фильмы).

Щелкните ссылку Create New (Создать). Введите в форму какие-либо недопустимые значения. Если функция проверки jQuery на стороне клиента обнаруживает ошибку, сведения о ней отображаются в соответствующем сообщении.

Форма просмотра фильма с несколькими ошибками проверки jQuery на стороне клиента

Примечание.

Возможно, вы не сможете вводить десятичные запятые в полях для десятичных чисел. Чтобы обеспечить поддержку проверки jQuery для других языков, кроме английского, используйте вместо десятичной точки запятую (","), а для отображения данных в форматах для других языков, кроме английского, выполните действия, необходимые для глобализации вашего приложения. См. этот комментарий GitHub 4076 для инструкций по добавлению десятичной запятой.

Обратите внимание, что для каждого поля, содержащего недопустимое значение, в форме автоматически отображается сообщение об ошибке проверки. Эти ошибки применяются как на стороне клиента (с помощью JavaScript и jQuery), так и на стороне сервера (если пользователь отключает JavaScript).

Основным преимуществом является то, что на страницах создания или редактирования не требуется изменять код. Пользовательский интерфейс проверки активируется после применения к модели атрибутов проверки достоверности. В Razor Pages, создаваемом в рамках этого руководства, правила проверки применяются автоматически (для этого к свойствам класса модели Movie применяются атрибуты проверки). При проверке страницы редактирования применяются те же правила.

Данные формы передаются на сервер только после того, как будут устранены все ошибки проверки на стороне клиента. Чтобы убедиться, что данные формы не отправляются, используйте любой из следующих способов.

  • Поместите точку останова в метод OnPostAsync. Отправьте форму, выбрав Создать или Сохранить. Точка останова не достигается ни при каких обстоятельствах.
  • Используйте инструмент Fiddler.
  • Проследите сетевой трафик с помощью инструментов разработчика для браузера.

Проверка на стороне сервера

Если в браузере отключен JavaScript, форма с ошибками отправляется на сервер.

Реализация проверки на стороне сервера:

  1. Отключите JavaScript в браузере. JavaScript можно отключить с помощью средств разработчика в браузере. Если JavaScript невозможно отключить в этом браузере, попробуйте использовать другой браузер.

  2. Поместите точку останова в метод OnPostAsync страниц создания или редактирования.

  3. Отправьте форму с недопустимыми данными.

  4. Проверка недопустимого состояния модели:

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

Иначе отключите проверку на стороне клиента на сервере.

В следующем коде демонстрируется часть страницы Create.cshtml, созданной ранее в рамках этого руководства. Она используется на страницах создания и редактирования для выполнения следующих действий:

  • Отображения начальной формы.
  • Повторного отображения формы в случае ошибки.
<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>

Вспомогательная функция тега Input использует атрибуты DataAnnotations и создает HTML-атрибуты, необходимые для проверки jQuery на стороне клиента. Вспомогательная функция тега Validation отображает ошибки проверки. Дополнительные сведения см. в разделе Проверка.

На страницах создания и редактирования не определены правила проверки. Правила проверки и строки ошибок указываются только в классе Movie. Они автоматически применяются к Razor Pages, которые редактируют модель Movie.

Любые необходимые изменения логики проверки осуществляются исключительно в модели. Проверка применяется последовательно во всем приложении, логика проверки определяется в одном месте. Такой подход позволяет максимально оптимизировать код и упростить его поддержку и обновление.

Использование атрибутов DataType

Проверьте класс Movie. В пространстве имен System.ComponentModel.DataAnnotations в дополнение к набору встроенных атрибутов проверки предоставляются атрибуты форматирования. Атрибут [DataType] применяется к свойствам ReleaseDate и Price.

[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }

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

Атрибуты [DataType] предоставляют:

  • Указания для обработчика представлений для форматирования данных.
  • Атрибуты, например <a> для URL-адресов и <a href="mailto:EmailAddress.com"> для электронной почты.

Используйте атрибут [RegularExpression] для проверки формата данных. Атрибут [DataType] позволяет указать тип данных с более точным определением по сравнению со встроенным типом базы данных. Атрибуты[DataType] не предназначены для проверки. В примере приложения отображается только дата без времени.

Перечисление DataType предоставляет множество типов данных, таких как Date, Time, PhoneNumber, Currency, EmailAddress и т. д.

Атрибуты [DataType]:

  • Может включить приложение для автоматического предоставления функций, относящихся к типу. Например, можно создавать ссылку mailto: для DataType.EmailAddress.
  • Могут предоставить селектор даты DataType.Date в браузерах, поддерживающих HTML5.
  • Создают атрибуты HTML 5 data-, которые используются браузерами с поддержкой HTML 5.
  • Не предназначены для проверки.

DataType.Date не задает формат отображаемой даты. По умолчанию поле данных отображается с использованием форматов, установленных в параметрах CultureInfo сервера.

Требуются заметки к данным [Column(TypeName = "decimal(18, 2)")], чтобы Entity Framework Core корректно сопоставила Price с валютой в базе данных. Дополнительные сведения см. в разделе Типы данных.

С помощью атрибута [DisplayFormat] можно явно указать формат даты:

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

Параметр ApplyFormatInEditMode указывает, что при отображении значения для редактирования будет применяться форматирование. Это поведение может быть нежелательным для некоторых полей. Например, в полях валюты в пользовательском интерфейсе редактирования использовать символ денежной единицы, как правило, не требуется.

Атрибут [DisplayFormat] может использоваться отдельно, однако чаще всего его рекомендуется применять вместе с атрибутом [DataType]. Атрибут [DataType] передает семантику данных (в отличие от способа их вывода на экран). Атрибут [DataType] дает следующие преимущества, недоступные в [DisplayFormat]:

  • Поддержка функций HTML5 в браузере, например отображение элемента управления календарем, соответствующего языковому стандарту символа валюты, ссылок электронной почты и т. д.
  • По умолчанию формат отображения данных в браузере определяется в соответствии с установленным языковым стандартом.
  • Атрибут [DataType] обеспечивает поддержку платформы ASP.NET Core для выбора соответствующего шаблона поля, применяемого при отображении данных. При отдельном использовании атрибут DisplayFormat базируется на строковом шаблоне.

Примечание. Проверка jQuery не работает с атрибутом [Range] и DateTime. Например, следующий код всегда приводит к возникновению ошибки проверки на стороне клиента, даже если дата попадает в указанный диапазон:

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

Лучшей методикой будет не компилировать модели с фиксированными датами, поэтому использовать атрибуты [Range] и DateTime следует крайне осторожно. Используйте конфигурацию для диапазонов дат и других значений, подверженных частым изменениям, а не указывайте их в коде.

В следующем коде демонстрируется объединение атрибутов в одной строке:

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

namespace RazorPagesMovie.Models;

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

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

    [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; } = string.Empty;

    [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; } = string.Empty;
}

Начало работы со Razor страницами и EF Core отображение расширенных EF Core операций с Razor Pages.

Применение миграции

DataAnnotation, примененные к классу, изменяют схему. Например, DataAnnotation, примеренные к полю Title, выполняют следующее:

[StringLength(60, MinimumLength = 3)]
[Required]
public string Title { get; set; } = string.Empty;
  • ограничивают число символов до 60;
  • не допускают значение null.

Сейчас таблица Movie имеет следующую схему:

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)
);

Предыдущие изменения схемы не приводят к созданию исключения EF. Но следует создать миграцию, чтобы схема соответствовала модели.

В меню Сервис последовательно выберите пункты Диспетчер пакетов NuGet > Консоль диспетчера пакетов. В PMC введите следующие команды:

Add-Migration New_DataAnnotations
Update-Database

Update-DatabaseUp запускает метод New_DataAnnotations класса.

Изучите метод Up:

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

        migrationBuilder.AlterColumn<string>(
            name: "Rating",
            table: "Movie",
            type: "nvarchar(5)",
            maxLength: 5,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");

        migrationBuilder.AlterColumn<string>(
            name: "Genre",
            table: "Movie",
            type: "nvarchar(30)",
            maxLength: 30,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");
    }

Обновленная таблица Movie имеет следующую схему:

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)
);

Публикация в Azure

Сведения о развертывании в Azure см. в руководстве по созданию приложения ASP.NET Core в Azure с помощью База данных SQL.

Благодарим вас за изучение общих сведений о страницах Razor. Начало работы с Razor Pages и EF Core отличное руководство.

Дополнительные ресурсы

Следующие шаги

В этом разделе к модели Movie добавляется логика проверки. Правила проверки применяются каждый раз, когда пользователь создает или редактирует фильм.

Проверка

Ключевой принцип разработки программного обеспечения называется DRY (от английского "Don't Repeat Yourself" — не повторяйся). При разработке Razor Pages рекомендуется задавать любые функциональные возможности лишь один раз и затем при необходимости отражать их в рамках всего приложения. Принцип "Не повторяйся" может помочь:

  • сократить объем кода в приложении;
  • снизить вероятность возникновения ошибки в коде и упростить его тестирование и поддержку.

Ярким примером применения принципа "Не повторяйся" является поддержка проверки, реализуемая в Razor Pages и на платформе Entity Framework:

  • Правила проверки декларативно определяются в одном месте, в классе модели.
  • Правила применяются по всему приложению.

Добавление правил проверки к модели фильма

Пространство имен System.ComponentModel.DataAnnotations предоставляет:

  • Набор встроенных атрибутов проверки, которые декларативно применяются к классу или свойству.
  • Атрибуты форматирования (такие как [DataType]), которые обеспечивают форматирование и не предназначены для проверки.

Обновите класс Movie, чтобы использовать преимущества встроенных атрибутов проверки [Required], [StringLength], [RegularExpression] и [Range].

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; } = string.Empty;

    // [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; } = string.Empty;

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

Атрибуты проверки определяют поведение для свойств модели, к которым они применяются:

  • Атрибуты [Required] и [MinimumLength] означают, что свойство должно иметь значение. Пользователь может свободно вводить пробелы для выполнения этой проверки.

  • Атрибут [RegularExpression] ограничивает набор допустимых для ввода символов. В приведенном выше коде в Genre:

    • должны использоваться только буквы;
    • первая буква должна быть прописной; Пробелы разрешены, а цифры и специальные символы — нет.
  • RegularExpressionRating:

    • первый символ должен быть прописной буквой;
    • допускаются специальные символы и цифры, а также последующие пробелы. значение "PG-13" допустимо для рейтинга, но недопустимо для Genre;
  • атрибут [Range] ограничивает значения указанным диапазоном.

  • Атрибут [StringLength] может задавать максимальную и, при необходимости, минимальную длину строкового свойства.

  • Типы значений (например, decimal, int, float, DateTime) по своей природе являются обязательными и не требуют атрибута [Required].

Указанные выше правила проверки используются для демонстрации, они не являются оптимальными для рабочей системы. Например, предыдущее исключение не позволяет ввести модель Movie с двумя символами и не допускает специальные знаки в Genre.

Наличие правил проверки, которые автоматически применяются ASP.NET Core, помогает:

  • сделать приложение более надежным;
  • сократить возможность сохранения недопустимых данных в базе данных.

Пользовательский интерфейс проверки ошибок в Razor Pages

Запустите приложение и перейдите в раздел "Pages/Movies" (Страницы/фильмы).

Щелкните ссылку Create New (Создать). Введите в форму какие-либо недопустимые значения. Если функция проверки jQuery на стороне клиента обнаруживает ошибку, сведения о ней отображаются в соответствующем сообщении.

Форма просмотра фильма с несколькими ошибками проверки jQuery на стороне клиента

Примечание.

Возможно, вы не сможете вводить десятичные запятые в полях для десятичных чисел. Чтобы обеспечить поддержку проверки jQuery для других языков, кроме английского, используйте вместо десятичной точки запятую (","), а для отображения данных в форматах для других языков, кроме английского, выполните действия, необходимые для глобализации вашего приложения. См. этот комментарий GitHub 4076 для инструкций по добавлению десятичной запятой.

Обратите внимание, что для каждого поля, содержащего недопустимое значение, в форме автоматически отображается сообщение об ошибке проверки. Эти ошибки применяются как на стороне клиента (с помощью JavaScript и jQuery), так и на стороне сервера (если пользователь отключает JavaScript).

Основным преимуществом является то, что на страницах создания или редактирования не требуется изменять код. Пользовательский интерфейс проверки активируется после применения к модели атрибутов проверки достоверности. В Razor Pages, создаваемом в рамках этого руководства, правила проверки применяются автоматически (для этого к свойствам класса модели Movie применяются атрибуты проверки). При проверке страницы редактирования применяются те же правила.

Данные формы передаются на сервер только после того, как будут устранены все ошибки проверки на стороне клиента. Чтобы убедиться, что данные формы не отправляются, используйте любой из следующих способов.

  • Поместите точку останова в метод OnPostAsync. Отправьте форму, выбрав Создать или Сохранить. Точка останова не достигается ни при каких обстоятельствах.
  • Используйте инструмент Fiddler.
  • Проследите сетевой трафик с помощью инструментов разработчика для браузера.

Проверка на стороне сервера

Если в браузере отключен JavaScript, форма с ошибками отправляется на сервер.

Реализация проверки на стороне сервера:

  1. Отключите JavaScript в браузере. JavaScript можно отключить с помощью средств разработчика в браузере. Если JavaScript невозможно отключить в этом браузере, попробуйте использовать другой браузер.

  2. Поместите точку останова в метод OnPostAsync страниц создания или редактирования.

  3. Отправьте форму с недопустимыми данными.

  4. Проверка недопустимого состояния модели:

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

Иначе отключите проверку на стороне клиента на сервере.

В следующем коде демонстрируется часть страницы Create.cshtml, созданной ранее в рамках этого руководства. Она используется на страницах создания и редактирования для выполнения следующих действий:

  • Отображения начальной формы.
  • Повторного отображения формы в случае ошибки.
<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>

Вспомогательная функция тега Input использует атрибуты DataAnnotations и создает HTML-атрибуты, необходимые для проверки jQuery на стороне клиента. Вспомогательная функция тега Validation отображает ошибки проверки. Дополнительные сведения см. в разделе Проверка.

На страницах создания и редактирования не определены правила проверки. Правила проверки и строки ошибок указываются только в классе Movie. Они автоматически применяются к Razor Pages, которые редактируют модель Movie.

Любые необходимые изменения логики проверки осуществляются исключительно в модели. Проверка применяется последовательно во всем приложении, логика проверки определяется в одном месте. Такой подход позволяет максимально оптимизировать код и упростить его поддержку и обновление.

Использование атрибутов DataType

Проверьте класс Movie. В пространстве имен System.ComponentModel.DataAnnotations в дополнение к набору встроенных атрибутов проверки предоставляются атрибуты форматирования. Атрибут [DataType] применяется к свойствам ReleaseDate и Price.

// [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; }

Атрибуты [DataType] предоставляют:

  • Указания для обработчика представлений для форматирования данных.
  • Атрибуты, например <a> для URL-адресов и <a href="mailto:EmailAddress.com"> для электронной почты.

Используйте атрибут [RegularExpression] для проверки формата данных. Атрибут [DataType] позволяет указать тип данных с более точным определением по сравнению со встроенным типом базы данных. Атрибуты[DataType] не предназначены для проверки. В примере приложения отображается только дата без времени.

Перечисление DataType предоставляет множество типов данных, таких как Date, Time, PhoneNumber, Currency, EmailAddress и т. д.

Атрибуты [DataType]:

  • Может включить приложение для автоматического предоставления функций, относящихся к типу. Например, можно создавать ссылку mailto: для DataType.EmailAddress.
  • Могут предоставить селектор даты DataType.Date в браузерах, поддерживающих HTML5.
  • Создают атрибуты HTML 5 data-, которые используются браузерами с поддержкой HTML 5.
  • Не предназначены для проверки.

DataType.Date не задает формат отображаемой даты. По умолчанию поле данных отображается с использованием форматов, установленных в параметрах CultureInfo сервера.

Требуются заметки к данным [Column(TypeName = "decimal(18, 2)")], чтобы Entity Framework Core корректно сопоставила Price с валютой в базе данных. Дополнительные сведения см. в разделе Типы данных.

С помощью атрибута [DisplayFormat] можно явно указать формат даты:

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

Параметр ApplyFormatInEditMode указывает, что при отображении значения для редактирования будет применяться форматирование. Это поведение может быть нежелательным для некоторых полей. Например, в полях валюты в пользовательском интерфейсе редактирования использовать символ денежной единицы, как правило, не требуется.

Атрибут [DisplayFormat] может использоваться отдельно, однако чаще всего его рекомендуется применять вместе с атрибутом [DataType]. Атрибут [DataType] передает семантику данных (в отличие от способа их вывода на экран). Атрибут [DataType] дает следующие преимущества, недоступные в [DisplayFormat]:

  • Поддержка функций HTML5 в браузере, например отображение элемента управления календарем, соответствующего языковому стандарту символа валюты, ссылок электронной почты и т. д.
  • По умолчанию формат отображения данных в браузере определяется в соответствии с установленным языковым стандартом.
  • Атрибут [DataType] обеспечивает поддержку платформы ASP.NET Core для выбора соответствующего шаблона поля, применяемого при отображении данных. При отдельном использовании атрибут DisplayFormat базируется на строковом шаблоне.

Примечание. Проверка jQuery не работает с атрибутом [Range] и DateTime. Например, следующий код всегда приводит к возникновению ошибки проверки на стороне клиента, даже если дата попадает в указанный диапазон:

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

Лучшей методикой будет не компилировать модели с фиксированными датами, поэтому использовать атрибуты [Range] и DateTime следует крайне осторожно. Используйте конфигурацию для диапазонов дат и других значений, подверженных частым изменениям, а не указывайте их в коде.

В следующем коде демонстрируется объединение атрибутов в одной строке:

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

namespace RazorPagesMovie.Models;

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

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

    [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; } = string.Empty;

    [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; } = string.Empty;
}

Начало работы со Razor страницами и EF Core отображение расширенных EF Core операций с Razor Pages.

Применение миграции

DataAnnotation, примененные к классу, изменяют схему. Например, DataAnnotation, примеренные к полю Title, выполняют следующее:

[StringLength(60, MinimumLength = 3)]
[Required]
public string Title { get; set; } = string.Empty;
  • ограничивают число символов до 60;
  • не допускают значение null.

Сейчас таблица Movie имеет следующую схему:

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)
);

Предыдущие изменения схемы не приводят к созданию исключения EF. Но следует создать миграцию, чтобы схема соответствовала модели.

В меню Сервис последовательно выберите пункты Диспетчер пакетов NuGet > Консоль диспетчера пакетов. В PMC введите следующие команды:

Add-Migration New_DataAnnotations
Update-Database

Update-DatabaseUp запускает метод New_DataAnnotations класса.

Изучите метод Up:

public partial class NewDataAnnotations : Migration
{
    /// <inheritdoc />
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.AlterColumn<string>(
            name: "Title",
            table: "Movie",
            type: "nvarchar(60)",
            maxLength: 60,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");

        migrationBuilder.AlterColumn<string>(
            name: "Rating",
            table: "Movie",
            type: "nvarchar(5)",
            maxLength: 5,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");

        migrationBuilder.AlterColumn<string>(
            name: "Genre",
            table: "Movie",
            type: "nvarchar(30)",
            maxLength: 30,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");
    }

Обновленная таблица Movie имеет следующую схему:

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)
);

Публикация в Azure

Сведения о развертывании в Azure см. в руководстве по созданию приложения ASP.NET Core в Azure с помощью База данных SQL.

Благодарим вас за изучение общих сведений о страницах Razor. Начало работы с Razor Pages и EF Core отличное руководство.

Дополнительные ресурсы

Следующие шаги

В этом разделе к модели Movie добавляется логика проверки. Правила проверки применяются каждый раз, когда пользователь создает или редактирует фильм.

Проверка

Ключевой принцип разработки программного обеспечения называется DRY (от английского "Don't Repeat Yourself" — не повторяйся). При разработке Razor Pages рекомендуется задавать любые функциональные возможности лишь один раз и затем при необходимости отражать их в рамках всего приложения. Принцип "Не повторяйся" может помочь:

  • сократить объем кода в приложении;
  • снизить вероятность возникновения ошибки в коде и упростить его тестирование и поддержку.

Ярким примером применения принципа "Не повторяйся" является поддержка проверки, реализуемая в Razor Pages и на платформе Entity Framework:

  • Правила проверки декларативно определяются в одном месте, в классе модели.
  • Правила применяются по всему приложению.

Добавление правил проверки к модели фильма

Пространство имен System.ComponentModel.DataAnnotations предоставляет:

  • Набор встроенных атрибутов проверки, которые декларативно применяются к классу или свойству.
  • Атрибуты форматирования (такие как [DataType]), которые обеспечивают форматирование и не предназначены для проверки.

Обновите класс Movie, чтобы использовать преимущества встроенных атрибутов проверки [Required], [StringLength], [RegularExpression] и [Range].

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; } = string.Empty;

        [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; } = string.Empty;

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

Атрибуты проверки определяют поведение для свойств модели, к которым они применяются:

  • Атрибуты [Required] и [MinimumLength] означают, что свойство должно иметь значение. Пользователь может свободно вводить пробелы для выполнения этой проверки.

  • Атрибут [RegularExpression] ограничивает набор допустимых для ввода символов. В приведенном выше коде в Genre:

    • должны использоваться только буквы;
    • первая буква должна быть прописной; Пробелы разрешены, а цифры и специальные символы — нет.
  • RegularExpressionRating:

    • первый символ должен быть прописной буквой;
    • допускаются специальные символы и цифры, а также последующие пробелы. значение "PG-13" допустимо для рейтинга, но недопустимо для Genre;
  • атрибут [Range] ограничивает значения указанным диапазоном.

  • Атрибут [StringLength] может задавать максимальную и, при необходимости, минимальную длину строкового свойства.

  • Типы значений (например, decimal, int, float, DateTime) по своей природе являются обязательными и не требуют атрибута [Required].

Указанные выше правила проверки используются для демонстрации, они не являются оптимальными для рабочей системы. Например, предыдущее исключение не позволяет ввести модель Movie с двумя символами и не допускает специальные знаки в Genre.

Наличие правил проверки, которые автоматически применяются ASP.NET Core, помогает:

  • сделать приложение более надежным;
  • сократить возможность сохранения недопустимых данных в базе данных.

Пользовательский интерфейс проверки ошибок в Razor Pages

Запустите приложение и перейдите в раздел "Pages/Movies" (Страницы/фильмы).

Щелкните ссылку Create New (Создать). Введите в форму какие-либо недопустимые значения. Если функция проверки jQuery на стороне клиента обнаруживает ошибку, сведения о ней отображаются в соответствующем сообщении.

Форма просмотра фильма с несколькими ошибками проверки jQuery на стороне клиента

Примечание.

Возможно, вы не сможете вводить десятичные запятые в полях для десятичных чисел. Чтобы обеспечить поддержку проверки jQuery для других языков, кроме английского, используйте вместо десятичной точки запятую (","), а для отображения данных в форматах для других языков, кроме английского, выполните действия, необходимые для глобализации вашего приложения. См. этот комментарий GitHub 4076 для инструкций по добавлению десятичной запятой.

Обратите внимание, что для каждого поля, содержащего недопустимое значение, в форме автоматически отображается сообщение об ошибке проверки. Эти ошибки применяются как на стороне клиента (с помощью JavaScript и jQuery), так и на стороне сервера (если пользователь отключает JavaScript).

Основным преимуществом является то, что на страницах создания или редактирования не требуется изменять код. Пользовательский интерфейс проверки активируется после применения к модели атрибутов проверки достоверности. В Razor Pages, создаваемом в рамках этого руководства, правила проверки применяются автоматически (для этого к свойствам класса модели Movie применяются атрибуты проверки). При проверке страницы редактирования применяются те же правила.

Данные формы передаются на сервер только после того, как будут устранены все ошибки проверки на стороне клиента. Чтобы убедиться, что данные формы не отправляются, используйте любой из следующих способов.

  • Поместите точку останова в метод OnPostAsync. Отправьте форму, выбрав Создать или Сохранить. Точка останова не достигается ни при каких обстоятельствах.
  • Используйте инструмент Fiddler.
  • Проследите сетевой трафик с помощью инструментов разработчика для браузера.

Проверка на стороне сервера

Если в браузере отключен JavaScript, форма с ошибками отправляется на сервер.

Реализация проверки на стороне сервера:

  1. Отключите JavaScript в браузере. JavaScript можно отключить с помощью средств разработчика в браузере. Если сделать это не удается, попробуйте использовать другой браузер.

  2. Поместите точку останова в метод OnPostAsync страниц создания или редактирования.

  3. Отправьте форму с недопустимыми данными.

  4. Проверка недопустимого состояния модели:

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

Иначе отключите проверку на стороне клиента на сервере.

В следующем коде демонстрируется часть страницы Create.cshtml, созданной ранее в рамках этого руководства. Она используется на страницах создания и редактирования для выполнения следующих действий:

  • Отображения начальной формы.
  • Повторного отображения формы в случае ошибки.
<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>

Вспомогательная функция тега Input использует атрибуты DataAnnotations и создает HTML-атрибуты, необходимые для проверки jQuery на стороне клиента. Вспомогательная функция тега Validation отображает ошибки проверки. Дополнительные сведения см. в разделе Проверка.

На страницах создания и редактирования не определены правила проверки. Правила проверки и строки ошибок указываются только в классе Movie. Они автоматически применяются к Razor Pages, которые редактируют модель Movie.

Любые необходимые изменения логики проверки осуществляются исключительно в модели. Проверка применяется согласованно на уровне всего приложения, для чего логика проверки определяется в одном месте. Такой подход позволяет максимально оптимизировать код и упростить его поддержку и обновление.

Использование атрибутов DataType

Проверьте класс Movie. В пространстве имен System.ComponentModel.DataAnnotations в дополнение к набору встроенных атрибутов проверки предоставляются атрибуты форматирования. Атрибут [DataType] применяется к свойствам ReleaseDate и Price.

[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; }

Атрибуты [DataType] предоставляют:

  • Указания для обработчика представлений для форматирования данных.
  • Атрибуты, например <a> для URL-адресов и <a href="mailto:EmailAddress.com"> для электронной почты.

Используйте атрибут [RegularExpression] для проверки формата данных. Атрибут [DataType] позволяет указать тип данных с более точным определением по сравнению со встроенным типом базы данных. Атрибуты[DataType] не предназначены для проверки. В том же приложении отображается только дата (без времени).

Перечисление DataType предоставляет множество типов данных, таких как Date, Time, PhoneNumber, Currency, EmailAddress и т. д.

Атрибуты [DataType]:

  • Обеспечивают автоматическое предоставление функций для определенных типов в приложении. Например, можно создавать ссылку mailto: для DataType.EmailAddress.
  • Могут предоставить селектор даты DataType.Date в браузерах, поддерживающих HTML5.
  • Создают атрибуты HTML 5 data-, которые используются браузерами с поддержкой HTML 5.
  • Не предназначены для проверки.

DataType.Date не задает формат отображаемой даты. По умолчанию поле данных отображается с использованием форматов, установленных в параметрах CultureInfo сервера.

Требуются заметки к данным [Column(TypeName = "decimal(18, 2)")], чтобы Entity Framework Core корректно сопоставила Price с валютой в базе данных. Дополнительные сведения см. в разделе Типы данных.

С помощью атрибута [DisplayFormat] можно явно указать формат даты:

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

Параметр ApplyFormatInEditMode указывает, что при отображении значения для редактирования будет применяться форматирование. Это поведение может быть нежелательным для некоторых полей. Например, в полях валюты в пользовательском интерфейсе редактирования использовать символ денежной единицы, как правило, не требуется.

Атрибут [DisplayFormat] может использоваться отдельно, однако чаще всего его рекомендуется применять вместе с атрибутом [DataType]. Атрибут [DataType] передает семантику данных (в отличие от способа их вывода на экран). Атрибут [DataType] дает следующие преимущества, недоступные в [DisplayFormat]:

  • Поддержка функций HTML5 в браузере, например отображение элемента управления календарем, соответствующего языковому стандарту символа валюты, ссылок электронной почты и т. д.
  • По умолчанию формат отображения данных в браузере определяется в соответствии с установленным языковым стандартом.
  • Атрибут [DataType] обеспечивает поддержку платформы ASP.NET Core для выбора соответствующего шаблона поля, применяемого при отображении данных. При отдельном использовании атрибут DisplayFormat базируется на строковом шаблоне.

Примечание. Проверка jQuery не работает с атрибутом [Range] и DateTime. Например, следующий код всегда приводит к возникновению ошибки проверки на стороне клиента, даже если дата попадает в указанный диапазон:

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

Лучшей методикой будет не компилировать модели с фиксированными датами, поэтому использовать атрибуты [Range] и DateTime следует крайне осторожно. Используйте конфигурацию для диапазонов дат и других значений, подверженных частым изменениям, а не указывайте их в коде.

В следующем коде демонстрируется объединение атрибутов в одной строке:

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)]
        public string Title { get; set; } = string.Empty;

        [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; } = string.Empty;

        [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; } = string.Empty;
    }
}

Начало работы со Razor страницами и EF Core отображение расширенных EF Core операций с Razor Pages.

Применение миграции

DataAnnotation, примененные к классу, изменяют схему. Например, DataAnnotation, примеренные к полю Title, выполняют следующее:

[StringLength(60, MinimumLength = 3)]
[Required]
public string Title { get; set; } = string.Empty;
  • ограничивают число символов до 60;
  • не допускают значение null.

Сейчас таблица Movie имеет следующую схему:

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)
);

Предыдущие изменения схемы не приводят к созданию исключения EF. Но следует создать миграцию, чтобы схема соответствовала модели.

В меню Сервис последовательно выберите пункты Диспетчер пакетов NuGet > Консоль диспетчера пакетов. В PMC введите следующие команды:

Add-Migration New_DataAnnotations
Update-Database

Update-DatabaseUp запускает метод New_DataAnnotations класса.

Изучите метод Up:

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

        migrationBuilder.AlterColumn<string>(
            name: "Rating",
            table: "Movie",
            type: "nvarchar(5)",
            maxLength: 5,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");

        migrationBuilder.AlterColumn<string>(
            name: "Genre",
            table: "Movie",
            type: "nvarchar(30)",
            maxLength: 30,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");
    }

Обновленная таблица Movie имеет следующую схему:

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)
);

Публикация в Azure

Сведения о развертывании в Azure см. в руководстве по созданию приложения ASP.NET Core в Azure с помощью База данных SQL.

Благодарим вас за изучение общих сведений о страницах Razor. Начало работы с Razor Pages и EF Core отличное руководство.

Дополнительные ресурсы

Следующие шаги

В этом разделе к модели Movie добавляется логика проверки. Правила проверки применяются каждый раз, когда пользователь создает или редактирует фильм.

Проверка

Ключевой принцип разработки программного обеспечения называется DRY (от английского "Don't Repeat Yourself" — не повторяйся). При разработке Razor Pages рекомендуется задавать любые функциональные возможности лишь один раз и затем при необходимости отражать их в рамках всего приложения. Принцип "Не повторяйся" может помочь:

  • сократить объем кода в приложении;
  • снизить вероятность возникновения ошибки в коде и упростить его тестирование и поддержку.

Ярким примером применения принципа "Не повторяйся" является поддержка проверки, реализуемая в Razor Pages и на платформе Entity Framework:

  • Правила проверки декларативно определяются в одном месте, в классе модели.
  • Правила применяются по всему приложению.

Добавление правил проверки к модели фильма

Пространство имен DataAnnotations предоставляет:

  • Набор встроенных атрибутов проверки, которые декларативно применяются к классу или свойству.
  • Атрибуты форматирования (такие как [DataType]), которые обеспечивают форматирование и не предназначены для проверки.

Обновите класс Movie, чтобы использовать преимущества встроенных атрибутов проверки [Required], [StringLength], [RegularExpression] и [Range].

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; }
    }
}

Атрибуты проверки определяют поведение для свойств модели, к которым они применяются:

  • Атрибуты [Required] и [MinimumLength] означают, что свойство должно иметь значение. Пользователь может свободно вводить пробелы для выполнения этой проверки.

  • Атрибут [RegularExpression] ограничивает набор допустимых для ввода символов. В приведенном выше коде в Genre:

    • должны использоваться только буквы;
    • первая буква должна быть прописной; Пробелы разрешены, а цифры и специальные символы — нет.
  • RegularExpressionRating:

    • первый символ должен быть прописной буквой;
    • допускаются специальные символы и цифры, а также последующие пробелы. значение "PG-13" допустимо для рейтинга, но недопустимо для Genre;
  • атрибут [Range] ограничивает значения указанным диапазоном.

  • Атрибут [StringLength] может задавать максимальную и, при необходимости, минимальную длину строкового свойства.

  • Типы значений (например, decimal, int, float, DateTime) по своей природе являются обязательными и не требуют атрибута [Required].

Указанные выше правила проверки используются для демонстрации, они не являются оптимальными для рабочей системы. Например, предыдущее исключение не позволяет ввести модель Movie с двумя символами и не допускает специальные знаки в Genre.

Наличие правил проверки, которые автоматически применяются ASP.NET Core, помогает:

  • сделать приложение более надежным;
  • сократить возможность сохранения недопустимых данных в базе данных.

Пользовательский интерфейс проверки ошибок в Razor Pages

Запустите приложение и перейдите в раздел "Pages/Movies" (Страницы/фильмы).

Щелкните ссылку Create New (Создать). Введите в форму какие-либо недопустимые значения. Если функция проверки jQuery на стороне клиента обнаруживает ошибку, сведения о ней отображаются в соответствующем сообщении.

Форма просмотра фильма с несколькими ошибками проверки jQuery на стороне клиента

Примечание.

Возможно, вы не сможете вводить десятичные запятые в полях для десятичных чисел. Чтобы обеспечить поддержку проверки jQuery для других языков, кроме английского, используйте вместо десятичной точки запятую (","), а для отображения данных в форматах для других языков, кроме английского, выполните действия, необходимые для глобализации вашего приложения. См. этот комментарий GitHub 4076 для инструкций по добавлению десятичной запятой.

Обратите внимание, что для каждого поля, содержащего недопустимое значение, в форме автоматически отображается сообщение об ошибке проверки. Эти ошибки применяются как на стороне клиента (с помощью JavaScript и jQuery), так и на стороне сервера (если пользователь отключает JavaScript).

Основным преимуществом является то, что на страницах создания или редактирования не требуется изменять код. Пользовательский интерфейс проверки активируется после применения к модели атрибутов проверки достоверности. В Razor Pages, создаваемом в рамках этого руководства, правила проверки применяются автоматически (для этого к свойствам класса модели Movie применяются атрибуты проверки). При проверке страницы редактирования применяются те же правила.

Данные формы передаются на сервер только после того, как будут устранены все ошибки проверки на стороне клиента. Чтобы убедиться, что данные формы не отправляются, используйте любой из следующих способов.

  • Поместите точку останова в метод OnPostAsync. Отправьте форму, выбрав Создать или Сохранить. Точка останова не достигается ни при каких обстоятельствах.
  • Используйте инструмент Fiddler.
  • Проследите сетевой трафик с помощью инструментов разработчика для браузера.

Проверка на стороне сервера

Если в браузере отключен JavaScript, форма с ошибками отправляется на сервер.

Реализация проверки на стороне сервера:

  1. Отключите JavaScript в браузере. JavaScript можно отключить с помощью средств разработчика в браузере. Если JavaScript невозможно отключить в этом браузере, попробуйте использовать другой браузер.

  2. Поместите точку останова в метод OnPostAsync страниц создания или редактирования.

  3. Отправьте форму с недопустимыми данными.

  4. Проверка недопустимого состояния модели:

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

Иначе отключите проверку на стороне клиента на сервере.

В следующем коде демонстрируется часть страницы Create.cshtml, созданной ранее в рамках этого руководства. Она используется на страницах создания и редактирования для выполнения следующих действий:

  • Отображения начальной формы.
  • Повторного отображения формы в случае ошибки.
<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>

Вспомогательная функция тега Input использует атрибуты DataAnnotations и создает HTML-атрибуты, необходимые для проверки jQuery на стороне клиента. Вспомогательная функция тега Validation отображает ошибки проверки. Дополнительные сведения см. в разделе Проверка.

На страницах создания и редактирования не определены правила проверки. Правила проверки и строки ошибок указываются только в классе Movie. Они автоматически применяются к Razor Pages, которые редактируют модель Movie.

Любые необходимые изменения логики проверки осуществляются исключительно в модели. Проверка применяется согласованно на уровне всего приложения, для чего логика проверки определяется в одном месте. Такой подход позволяет максимально оптимизировать код и упростить его поддержку и обновление.

Использование атрибутов DataType

Проверьте класс Movie. В пространстве имен System.ComponentModel.DataAnnotations в дополнение к набору встроенных атрибутов проверки предоставляются атрибуты форматирования. Атрибут [DataType] применяется к свойствам ReleaseDate и Price.

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

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

Атрибуты [DataType] предоставляют:

  • Указания для обработчика представлений для форматирования данных.
  • Атрибуты, например <a> для URL-адресов и <a href="mailto:EmailAddress.com"> для электронной почты.

Используйте атрибут [RegularExpression] для проверки формата данных. Атрибут [DataType] позволяет указать тип данных с более точным определением по сравнению со встроенным типом базы данных. Атрибуты[DataType] не предназначены для проверки. В том же приложении отображается только дата (без времени).

Перечисление DataType предоставляет множество типов данных, таких как Date, Time, PhoneNumber, Currency, EmailAddress и т. д.

Атрибуты [DataType]:

  • Обеспечивают автоматическое предоставление функций для определенных типов в приложении. Например, можно создавать ссылку mailto: для DataType.EmailAddress.
  • Могут предоставить селектор даты DataType.Date в браузерах, поддерживающих HTML5.
  • Создают атрибуты HTML 5 data-, которые используются браузерами с поддержкой HTML 5.
  • Не предназначены для проверки.

DataType.Date не задает формат отображаемой даты. По умолчанию поле данных отображается с использованием форматов, установленных в параметрах CultureInfo сервера.

Требуются заметки к данным [Column(TypeName = "decimal(18, 2)")], чтобы Entity Framework Core корректно сопоставила Price с валютой в базе данных. Дополнительные сведения см. в разделе Типы данных.

С помощью атрибута [DisplayFormat] можно явно указать формат даты:

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

Параметр ApplyFormatInEditMode указывает, что при отображении значения для редактирования будет применяться форматирование. Это поведение может быть нежелательным для некоторых полей. Например, в полях валюты в пользовательском интерфейсе редактирования использовать символ денежной единицы, как правило, не требуется.

Атрибут [DisplayFormat] может использоваться отдельно, однако чаще всего его рекомендуется применять вместе с атрибутом [DataType]. Атрибут [DataType] передает семантику данных (в отличие от способа их вывода на экран). Атрибут [DataType] дает следующие преимущества, недоступные в [DisplayFormat]:

  • Поддержка функций HTML5 в браузере, например отображение элемента управления календарем, соответствующего языковому стандарту символа валюты, ссылок электронной почты и т. д.
  • По умолчанию формат отображения данных в браузере определяется в соответствии с установленным языковым стандартом.
  • Атрибут [DataType] обеспечивает поддержку платформы ASP.NET Core для выбора соответствующего шаблона поля, применяемого при отображении данных. При отдельном использовании атрибут DisplayFormat базируется на строковом шаблоне.

Примечание. Проверка jQuery не работает с атрибутом [Range] и DateTime. Например, следующий код всегда приводит к возникновению ошибки проверки на стороне клиента, даже если дата попадает в указанный диапазон:

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

Лучшей методикой будет не компилировать модели с фиксированными датами, поэтому использовать атрибуты [Range] и DateTime следует крайне осторожно. Используйте конфигурацию для диапазонов дат и других значений, подверженных частым изменениям, а не указывайте их в коде.

В следующем коде демонстрируется объединение атрибутов в одной строке:

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; }
}

Начало работы со Razor страницами и EF Core отображение расширенных EF Core операций с Razor Pages.

Применение миграции

DataAnnotation, примененные к классу, изменяют схему. Например, DataAnnotation, примеренные к полю Title, выполняют следующее:

[StringLength(60, MinimumLength = 3)]
[Required]
public string Title { get; set; }
  • ограничивают число символов до 60;
  • не допускают значение null.

Сейчас таблица Movie имеет следующую схему:

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)
);

Предыдущие изменения схемы не приводят к созданию исключения EF. Но следует создать миграцию, чтобы схема соответствовала модели.

В меню Сервис последовательно выберите пункты Диспетчер пакетов NuGet > Консоль диспетчера пакетов. В PMC введите следующие команды:

Add-Migration New_DataAnnotations
Update-Database

Update-Database выполняет методы Up класса New_DataAnnotations. Изучите метод Up:

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);
    }

Обновленная таблица Movie имеет следующую схему:

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)
);

Публикация в Azure

Сведения о развертывании в Azure см. в руководстве по созданию приложения ASP.NET Core в Azure с помощью База данных SQL.

Благодарим вас за изучение общих сведений о страницах Razor. Начало работы с Razor Pages и EF Core отличное руководство.

Надежные шаблоны веб-приложений

См . статью "Шаблон надежных веб-приложений" for.NETвидео и статьи YouTube по созданию современного, надежного, производительного, тестового, экономичного и масштабируемого приложения ASP.NET Core, будь то с нуля или рефакторинг существующего приложения.

Дополнительные ресурсы

Следующие шаги