Обучение
Модуль
Улучшение работы форм и проверки в веб-приложениях Blazor - Training
Сведения об использовании событий, форм и проверки модели DOM в приложении Blazor
Этот браузер больше не поддерживается.
Выполните обновление до Microsoft Edge, чтобы воспользоваться новейшими функциями, обновлениями для системы безопасности и технической поддержкой.
Примечание
Это не последняя версия этой статьи. В текущем выпуске см . версию .NET 9 этой статьи.
Предупреждение
Эта версия ASP.NET Core больше не поддерживается. Дополнительные сведения см. в политике поддержки .NET и .NET Core. В текущем выпуске см . версию .NET 9 этой статьи.
Важно!
Эта информация относится к предварительному выпуску продукта, который может быть существенно изменен до его коммерческого выпуска. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
В текущем выпуске см . версию .NET 9 этой статьи.
В этой статье объясняется, как использовать формы в Blazor.
Платформа Blazor поддерживает формы и предоставляет встроенные компоненты ввода:
<form>
.Примечание
Неподдерживаемые функции проверки ASP.NET Core рассматриваются в разделе неподдерживаемых функций проверки.
Пространство имен Microsoft.AspNetCore.Components.Forms предоставляет:
Проект, созданный из Blazor шаблона проекта, включает пространство имен в файл приложения _Imports.razor
, что делает пространство имен доступным для компонентов приложения Razor .
Поддерживаются стандартные ФОРМЫ HTML. Создайте форму с помощью обычного HTML-тега <form>
и укажите @onsubmit
обработчик для обработки отправленного запроса формы.
StarshipPlainForm.razor
:
@page "/starship-plain-form"
@inject ILogger<StarshipPlainForm> Logger
<form method="post" @onsubmit="Submit" @formname="starship-plain-form">
<AntiforgeryToken />
<div>
<label>
Identifier:
<InputText @bind-Value="Model!.Id" />
</label>
</div>
<div>
<button type="submit">Submit</button>
</div>
</form>
@code {
[SupplyParameterFromForm]
private Starship? Model { get; set; }
protected override void OnInitialized() => Model ??= new();
private void Submit() => Logger.LogInformation("Id = {Id}", Model?.Id);
public class Starship
{
public string? Id { get; set; }
}
}
@page "/starship-plain-form"
@inject ILogger<StarshipPlainForm> Logger
<form method="post" @onsubmit="Submit" @formname="starship-plain-form">
<AntiforgeryToken />
<div>
<label>
Identifier:
<InputText @bind-Value="Model!.Id" />
</label>
</div>
<div>
<button type="submit">Submit</button>
</div>
</form>
@code {
[SupplyParameterFromForm]
private Starship? Model { get; set; }
protected override void OnInitialized() => Model ??= new();
private void Submit() => Logger.LogInformation("Id = {Id}", Model?.Id);
public class Starship
{
public string? Id { get; set; }
}
}
В предыдущем компоненте StarshipPlainForm
:
<form>
отображается элемент. Форма называется атрибутом @formname
директивы, который однозначно идентифицирует форму в Blazor платформе.@code
компонента и хранится в общедоступном свойстве (Model
). Атрибут [SupplyParameterFromForm]
указывает, что значение связанного свойства должно быть предоставлено из данных формы. Данные в запросе, который соответствует имени свойства, привязаны к свойству.@bind-Value
привязывает свойство модели Model.Id
к свойству InputText компонента Value.Submit
регистрируется в качестве обработчика для обратного @onsubmit
вызова. Обработчик вызывается, когда форма отправляется пользователем.Важно!
Всегда используйте атрибут директивы @formname
с уникальным именем формы.
Blazor улучшает навигацию по страницам и обработку форм путем перехвата запроса, чтобы применить ответ к существующей модели DOM, сохраняя столько отрисованной формы, сколько это возможно. Это улучшение позволяет избежать полной загрузки страницы и обеспечивает более плавное взаимодействие с пользователем, аналогичное одностраничного приложения (SPA), хотя компонент отрисовывается на сервере. Дополнительные сведения см. в статье Маршрутизация ASP.NET Core Blazor и навигация.
Потоковая отрисовка поддерживается для простых HTML-форм.
Примечание
По ссылкам в документации на справочные материалы по .NET обычно загружается ветвь репозитория по умолчанию, которая представляет текущую разработку для следующего выпуска .NET. Чтобы выбрать тег для определенного выпуска, используйте раскрывающийся список Switch branches or tags (Переключение ветвей или тегов). Дополнительные сведения см. в статье Выбор тега версии исходного кода ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Предыдущий пример включает поддержку антифоргерии, включив AntiforgeryToken компонент в форму. Поддержка антифоргерии объясняется далее в разделе поддержки Antiforgery этой статьи.
Чтобы отправить форму на основе событий DOM другого элемента, напримерoninput
, используйте JavaScript для отправки формы (submit
).
Вместо использования простых форм в Blazor приложениях форма обычно определяется со Blazorвстроенной поддержкой форм с помощью компонента платформы EditForm . Razor Следующий компонент демонстрирует типичные элементы, компоненты и Razor код для отрисовки EditForm веб-формы с помощью компонента.
Форма определяется с помощью компонента Blazor платформы EditForm. Razor Следующий компонент демонстрирует типичные элементы, компоненты и Razor код для отрисовки EditForm веб-формы с помощью компонента.
Starship1.razor
:
@page "/starship-1"
@inject ILogger<Starship1> Logger
<EditForm Model="Model" OnSubmit="Submit" FormName="Starship1">
<div>
<label>
Identifier:
<InputText @bind-Value="Model!.Id" />
</label>
</div>
<div>
<button type="submit">Submit</button>
</div>
</EditForm>
@code {
[SupplyParameterFromForm]
private Starship? Model { get; set; }
protected override void OnInitialized() => Model ??= new();
private void Submit() => Logger.LogInformation("Id = {Id}", Model?.Id);
public class Starship
{
public string? Id { get; set; }
}
}
@page "/starship-1"
@inject ILogger<Starship1> Logger
<EditForm Model="Model" OnSubmit="Submit" FormName="Starship1">
<div>
<label>
Identifier:
<InputText @bind-Value="Model!.Id" />
</label>
</div>
<div>
<button type="submit">Submit</button>
</div>
</EditForm>
@code {
[SupplyParameterFromForm]
private Starship? Model { get; set; }
protected override void OnInitialized() => Model ??= new();
private void Submit() => Logger.LogInformation("Id = {Id}", Model?.Id);
public class Starship
{
public string? Id { get; set; }
}
}
В предыдущем компоненте Starship1
:
<EditForm>
. Форма называется свойством FormName, которое однозначно идентифицирует форму для платформы Blazor.@code
компонента и хранится в общедоступном свойстве (Model
). Свойство назначается параметру EditForm.Model . Атрибут [SupplyParameterFromForm]
указывает, что значение связанного свойства должно быть предоставлено из данных формы. Данные в запросе, который соответствует имени свойства, привязаны к свойству.@bind-Value
привязывает свойство модели Model.Id
к свойству InputText компонента Value.Submit
регистрируется в качестве обработчика для обратного OnSubmit вызова. Обработчик вызывается, когда форма отправляется пользователем.Важно!
Всегда используйте свойство FormName с уникальным именем формы.
Blazor улучшает навигацию по страницам и обработку форм для EditForm компонентов. Дополнительные сведения см. в статье Маршрутизация ASP.NET Core Blazor и навигация.
Потоковая отрисовка поддерживается для EditForm.
Примечание
По ссылкам в документации на справочные материалы по .NET обычно загружается ветвь репозитория по умолчанию, которая представляет текущую разработку для следующего выпуска .NET. Чтобы выбрать тег для определенного выпуска, используйте раскрывающийся список Switch branches or tags (Переключение ветвей или тегов). Дополнительные сведения см. в статье Выбор тега версии исходного кода ASP.NET Core (dotnet/AspNetCore.Docs #26205).
@page "/starship-1"
@inject ILogger<Starship1> Logger
<EditForm Model="Model" OnSubmit="Submit">
<InputText @bind-Value="Model!.Id" />
<button type="submit">Submit</button>
</EditForm>
@code {
public Starship? Model { get; set; }
protected override void OnInitialized() => Model ??= new();
private void Submit()
{
Logger.LogInformation("Model.Id = {Id}", Model?.Id);
}
public class Starship
{
public string? Id { get; set; }
}
}
В предыдущем компоненте Starship1
:
<EditForm>
.@code
компонента и хранится в частном поле (model
). Поле назначается параметру EditForm.Model .@bind-Value
Атрибут директивы привязывает Model.Id
свойство модели к InputText свойству компонентаValue†.Submit
регистрируется в качестве обработчика для обратного OnSubmit вызова. Обработчик вызывается, когда форма отправляется пользователем.† Для получения дополнительных сведений о привязке Blazor свойств см. ASP.NET привязка основных данных.
В следующем примере предыдущий компонент изменяется, чтобы создать форму в компоненте Starship2
:
<input>
поле формы Submit
остается пустым, в сводке по проверке (компонент ValidationSummary‡) появляется сообщение об ошибке (The Id field is required.
) и Submit
не вызывается.<input>
Если поле формы содержит более десяти символов при Submit
выборе кнопки, в сводке проверки отображается ошибка ("Id is too long.
").
Submit
не вызывается.<input>
поле формы Submit
содержит допустимое значение, Submit
вызывается.†Компонент DataAnnotationsValidator рассматривается в разделе Компонент проверяющего элемента управления. ‡Компонент ValidationSummary рассматривается в разделе Сводка проверки и компоненты сообщений о проверке.
Starship2.razor
:
@page "/starship-2"
@using System.ComponentModel.DataAnnotations
@inject ILogger<Starship2> Logger
<EditForm Model="Model" OnValidSubmit="Submit" FormName="Starship2">
<DataAnnotationsValidator />
<ValidationSummary />
<label>
Identifier:
<InputText @bind-Value="Model!.Id" />
</label>
<button type="submit">Submit</button>
</EditForm>
@code {
[SupplyParameterFromForm]
private Starship? Model { get; set; }
protected override void OnInitialized() => Model ??= new();
private void Submit() => Logger.LogInformation("Id = {Id}", Model?.Id);
public class Starship
{
[Required]
[StringLength(10, ErrorMessage = "Id is too long.")]
public string? Id { get; set; }
}
}
@page "/starship-2"
@using System.ComponentModel.DataAnnotations
@inject ILogger<Starship2> Logger
<EditForm Model="Model" OnValidSubmit="Submit" FormName="Starship2">
<DataAnnotationsValidator />
<ValidationSummary />
<label>
Identifier:
<InputText @bind-Value="Model!.Id" />
</label>
<button type="submit">Submit</button>
</EditForm>
@code {
[SupplyParameterFromForm]
private Starship? Model { get; set; }
protected override void OnInitialized() => Model ??= new();
private void Submit() => Logger.LogInformation("Id = {Id}", Model?.Id);
public class Starship
{
[Required]
[StringLength(10, ErrorMessage = "Id is too long.")]
public string? Id { get; set; }
}
}
@page "/starship-2"
@using System.ComponentModel.DataAnnotations
@inject ILogger<Starship2> Logger
<EditForm Model="Model" OnValidSubmit="Submit">
<DataAnnotationsValidator />
<ValidationSummary />
<InputText @bind-Value="Model!.Id" />
<button type="submit">Submit</button>
</EditForm>
@code {
public Starship? Model { get; set; }
protected override void OnInitialized() => Model ??= new();
private void Submit()
{
Logger.LogInformation("Id = {Id}", Model?.Id);
}
public class Starship
{
[Required]
[StringLength(10, ErrorMessage = "Id is too long.")]
public string? Id { get; set; }
}
}
EditForm предоставляет следующие обратные вызовы для обработки отправки формы:
true
, форма является допустимой.Сброс формы путем очистки модели обратно его состояния по умолчанию, которое можно выполнить внутри или за пределами EditFormразметки:
<button @onclick="ClearForm">Clear form</button>
...
private void ClearForm() => Model = new();
Кроме того, используйте явное Razor выражение:
<button @onclick="@(() => Model = new())">Clear form</button>
Сброс поля путем очистки значения модели обратно в состояние по умолчанию:
<button @onclick="ResetId">Reset Identifier</button>
...
private void ResetId() => Model!.Id = string.Empty;
Кроме того, используйте явное Razor выражение:
<button @onclick="@(() => Model!.Id = string.Empty)">Reset Identifier</button>
В предыдущих примерах не требуется вызываться StateHasChanged , так как StateHasChanged платформа автоматически вызывает Blazor компонент после вызова обработчика событий. Если обработчик событий не используется для вызова методов, которые очищают форму или поле, то код разработчика должен вызывать StateHasChanged rerender the component.
Службы антифоргерии автоматически добавляются в Blazor приложения при AddRazorComponents вызове Program
в файле.
Приложение использует по промежуточному слоям антифоргерии, вызывая UseAntiforgery его конвейер обработки запросов в Program
файле.
UseAntiforgery вызывается после вызова UseRouting. Если есть вызовы UseRouting и UseEndpoints, вызов UseAntiforgery должен пройти между ними. Вызов UseAntiforgery должен быть помещен после вызовов UseAuthentication и UseAuthorization.
Компонент AntiforgeryToken отображает маркер антифоргерии в виде скрытого поля, а [RequireAntiforgeryToken]
атрибут обеспечивает защиту от антифоргерии. Если проверка защиты завершается ошибкой, 400 - Bad Request
создается ответ и форма не обрабатывается.
Для форм на основе EditFormкомпонентов AntiforgeryToken и [RequireAntiforgeryToken]
атрибутов автоматически добавляются для обеспечения защиты от подделки.
Для форм на основе HTML-элемента <form>
вручную добавьте AntiforgeryToken компонент в форму:
<form method="post" @onsubmit="Submit" @formname="starshipForm">
<AntiforgeryToken />
<input id="send" type="submit" value="Send" />
</form>
@if (submitted)
{
<p>Form submitted!</p>
}
@code{
private bool submitted = false;
private void Submit() => submitted = true;
}
Предупреждение
Для форм на EditForm основе элемента HTML <form>
защита от антифоргерии может быть отключена путем передачи required: false
атрибуту [RequireAntiforgeryToken]
. Следующий пример отключает антифоргерию и не рекомендуется для общедоступных приложений:
@using Microsoft.AspNetCore.Antiforgery
@attribute [RequireAntiforgeryToken(required: false)]
Статически отрисованные серверные формы, например те, которые обычно используются в компонентах, которые создают и редактируют записи в базе данных с моделью формы, могут быть уязвимыми к атаке переположений , также называемой атакой массового назначения . Атака переступа возникает, когда злоумышленник выдает HTML-форму POST на сервер, который обрабатывает данные для свойств, не входящих в отрисованную форму, и что разработчик не хочет изменять пользователей. Термин "overposting" буквально означает, что вредоносный пользователь переназначил posTed с формой.
Перепоступение не является проблемой, если модель не включает ограниченные свойства для операций создания и обновления. Однако при работе со статическими формами на основе Blazor SSR важно учитывать избыточность.
Чтобы устранить переступ, рекомендуется использовать отдельную модель представления или объект передачи данных (DTO) для формы и базы данных с помощью операций создания (вставки) и обновления. При отправке формы для изменения базы данных используются только свойства модели представления или DTO компонента и кода C#. Все дополнительные данные, включенные вредоносным пользователем, удаляются, поэтому злоумышленник не может вести атаку на переположение.
Улучшена навигация по запросам Enhance POST формы с помощью параметра форм EditForm или data-enhance
атрибута для форм HTML (<form>
):
<EditForm ... Enhance ...>
...
</EditForm>
<form ... data-enhance ...>
...
</form>
Неподдерживаемый: невозможно задать расширенную навигацию по элементу предка формы, чтобы обеспечить улучшенную обработку форм.
<div ... data-enhance ...>
<form ...>
<!-- NOT enhanced -->
</form>
</div>
Расширенные записи форм работают только с Blazor конечными точками. Публикация расширенной формы в неконечнуюBlazor точку приводит к ошибке.
Чтобы отключить расширенную обработку форм, выполните приведенные действия.
false
значение : Enhance="false"
).<form>
удалите data-enhance
атрибут из элемента формы (или задайте для него false
значение : data-enhance="false"
).
BlazorУлучшенная навигация и передача форм могут отменить динамические изменения в DOM, если обновленное содержимое не является частью отрисовки сервера. Чтобы сохранить содержимое элемента, используйте data-permanent
атрибут.
В следующем примере содержимое <div>
элемента динамически обновляется скриптом при загрузке страницы:
<div data-permanent>
...
</div>
Сведения об отключении расширенной навигации и глобальной обработки форм см. в разделе Blazor Core.
Рекомендации по использованию enhancedload
события для прослушивания расширенных обновлений страниц см. в разделе ASP.NET Базовая Blazor маршрутизация и навигация.
Примеры не применяют расширенную обработку форм для запросов POST формы, но все примеры можно обновить для внедрения расширенных функций, следуя инструкциям в разделе "Улучшенная обработка форм".
Примеры используют целевой типизированный new
оператор, который был представлен с C# 9.0 и .NET 5. В следующем примере тип не указан явным new
образом для оператора:
public ShipDescription ShipDescription { get; set; } = new();
При использовании C# 8.0 или более ранней версии (ASP.NET Core 3.1) измените пример кода, чтобы указать тип оператору new
:
public ShipDescription ShipDescription { get; set; } = new ShipDescription();
Компоненты используют ссылочные типы, допускающие значение NULL (NRT), и компилятор .NET выполняет статический анализ состояния NULL, оба из которых поддерживаются в .NET 6 или более поздней версии. Дополнительные сведения см. в статье Миграция с ASP.NET Core 5.0 на 6.0.
При использовании C# 9.0 или более ранней версии (.NET 5 или более ранней версии) удалите NRT из примеров. Как правило, это просто включает удаление вопросительных знаков () и восклицательных точек (?
!
) из типов в примере кода.
Пакет SDK для .NET применяет неявные глобальные using
директивы к проектам при выборе .NET 6 или более поздней версии. В примерах используется средство ведения журнала для записи сведений об обработке форм, но не требуется указывать @using
директиву для Microsoft.Extensions.Logging пространства имен в примерах компонентов. Дополнительные сведения см. в пакетах SDK для проекта .NET: неявные директивы using.
При использовании C# 9.0 или более ранней версии (.NET 5 или более ранней версии) добавьте @using
директивы в верхнюю часть компонента после @page
директивы для любого API, необходимого в примере. Найдите пространства имен API через Visual Studio (щелкните объект правой кнопкой мыши и выберите "Показать определение") или браузер API .NET.
Чтобы продемонстрировать, как формы работают с проверкой заметок данных, примеры компонентов используют System.ComponentModel.DataAnnotations API. Если вы хотите избежать дополнительной строки кода в компонентах, использующих заметки данных, сделайте пространство имен доступным на всех компонентах приложения с файлом импорта (_Imports.razor
):
@using System.ComponentModel.DataAnnotations
Примеры форм ссылались на аспекты вселенной Star Trek . Star Trek является авторским правом ©1966-2023 CBS Studio и Paramount.
Для Blazor Web Appпроверки на стороне клиента требуется активный BlazorSignalR канал. Проверка на стороне клиента недоступна для форм в компонентах, которые приняли статическую отрисовку на стороне сервера (статический SSR). Формы, использующие статический SSR, проверяются на сервере после отправки формы.
Все встроенные проверяющие средства заметки данных поддерживаются Blazor за исключением атрибута [Remote]
проверки.
Проверка jQuery не поддерживается в Razor компонентах. Мы рекомендуем использовать любой из следующих подходов:
Для статически отрисовываемых форм на сервере в конце 2025 года рассматривается новый механизм проверки на стороне клиента. Дополнительные сведения см. в статье "Создание форм, отрисованных сервером, с использованием Blazor проверки клиента без канала (dotnet/aspnetcore
#51040)".
dotnet/blazor-samples
как скачать)dotnet/aspnetcore
) тестовые ресурсы формОтзыв о ASP.NET Core
ASP.NET Core — это проект с открытым исходным кодом. Выберите ссылку, чтобы оставить отзыв:
Обучение
Модуль
Улучшение работы форм и проверки в веб-приложениях Blazor - Training
Сведения об использовании событий, форм и проверки модели DOM в приложении Blazor