Поделиться через


Blazor Обзор основных форм ASP.NET

Примечание.

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

Предупреждение

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

Внимание

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

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

В этой статье объясняется, как использовать формы в Blazor.

Входные компоненты и формы

Платформа Blazor поддерживает формы и предоставляет встроенные компоненты ввода:

Примечание.

Неподдерживаемые функции проверки ASP.NET Core рассматриваются в разделе неподдерживаемых функций проверки.

Пространство имен Microsoft.AspNetCore.Components.Forms предоставляет:

  • Классы для управления элементами формы, состоянием и проверкой.
  • Доступ к встроенным Input* компонентам.

Проект, созданный из 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] указывает, что значение связанного свойства должно быть предоставлено из данных формы. Данные в запросе, который соответствует имени свойства, привязаны к свойству.
  • Компонент InputText является входным компонентом для редактирования строковых значений. Атрибут директивы @bind-Value привязывает свойство модели Model.Id к свойству Value компонента InputText.
  • Метод 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(документация по MDN)).onblur

Вместо использования простых форм в Blazor приложениях форма обычно определяется со Blazorвстроенной поддержкой форм с помощью компонента платформы EditForm . Razor Следующий компонент демонстрирует типичные элементы, компоненты и Razor код для отрисовки EditForm веб-формы с помощью компонента.

Форма определяется с помощью компонента EditForm платформы Blazor. 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 отображается там, где находится элемент <EditForm>. Форма называется атрибутом @formname директивы, который однозначно идентифицирует форму в Blazor платформе.
  • Модель создается в блоке @code компонента и хранится в общедоступном свойстве (Model). Свойство назначается параметру EditForm.Model . Атрибут [SupplyParameterFromForm] указывает, что значение связанного свойства должно быть предоставлено из данных формы. Данные в запросе, который соответствует имени свойства, привязаны к свойству.
  • Компонент InputText является входным компонентом для редактирования строковых значений. Атрибут директивы @bind-Value привязывает свойство модели Model.Id к свойству Value компонента InputText.
  • Метод 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 отображается там, где находится элемент <EditForm>.
  • Модель создается в блоке @code компонента и хранится в частном поле (model). Поле назначается параметру EditForm.Model .
  • Компонент InputText является входным компонентом для редактирования строковых значений. @bind-Value Атрибут директивы привязывает Model.Id свойство модели к InputText свойству компонентаValue†.
  • Метод Submit регистрируется в качестве обработчика для обратного OnSubmit вызова. Обработчик вызывается, когда форма отправляется пользователем.

† Для получения дополнительных сведений о привязке Blazor свойств см. ASP.NET привязка основных данных.

В следующем примере предыдущий компонент изменяется, чтобы создать форму в компоненте Starship2 :

  • OnSubmit заменяется OnValidSubmitобработчиком событий, который обрабатывает назначенный обработчик событий, если форма действительна при отправке пользователем.
  • Компонент ValidationSummary добавляется для отображения сообщений проверки, когда форма недопустима при отправке формы.
  • Проверяющий элемент проверки данных (DataAnnotationsValidator компонент†) подключает поддержку проверки с помощью заметок данных:
    • Если при нажатии кнопки Submit поле формы <input> остается пустым, в сводке по проверке (компонент ValidationSummary‡) появляется сообщение об ошибке (The Id field is required.) и Submit не вызывается.
    • <input> Если поле формы содержит более десяти символов при Submit выборе кнопки, в сводке проверки отображается ошибка ("Id is too long."). Submitне вызывается.
    • Если при нажатии кнопки Submit поле формы <input> содержит допустимое значение, 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 предоставляет следующие обратные вызовы для обработки отправки формы:

  • Используйте OnValidSubmit, чтобы обработчик событий запускался при отправке формы с допустимыми полями.
  • Используйте OnInvalidSubmit, чтобы обработчик событий запускался при отправке формы с недопустимыми полями.
  • Используйте OnSubmit, чтобы обработчик событий запускался независимо от состояния проверки полей формы. Форма проверяется путем вызова EditContext.Validate в методе обработчика событий. Если Validate возвращает 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)]

Дополнительные сведения см. в разделе ASP.NET Проверка подлинности и авторизация CoreBlazor.

Устранение перепоставок атак

Статически отрисованные серверные формы, например те, которые обычно используются в компонентах, которые создают и редактируют записи в базе данных с моделью формы, могут быть уязвимыми к атаке переположений , также называемой атакой массового назначения . Атака переступа возникает, когда злоумышленник выдает 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 точку приводит к ошибке.

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

  • EditFormДля параметра удалите Enhance параметр из элемента формы (или задайте для него falseзначение : Enhance="false").
  • Для HTML <form>удалите data-enhance атрибут из элемента формы (или задайте для него falseзначение : data-enhance="false").

BlazorУлучшенная навигация и передача форм могут отменить динамические изменения в DOM, если обновленное содержимое не является частью отрисовки сервера. Чтобы сохранить содержимое элемента, используйте data-permanent атрибут.

В следующем примере содержимое <div> элемента динамически обновляется скриптом при загрузке страницы:

<div data-permanent>
    ...
</div>

Сведения об отключении расширенной навигации и глобальной обработки форм см. в разделе ASP.NET Запуск CoreBlazor.

Рекомендации по использованию 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 компонентах. Мы рекомендуем использовать любой из следующих подходов:

  • Следуйте инструкциям в ASP.NET проверке Blazor основных форм для любого из следующих вариантов:
    • Проверка на стороне сервера в Blazor Web App режиме интерактивной отрисовки.
    • Проверка на стороне клиента в автономном Blazor веб-приложении сборки.
  • Используйте собственные атрибуты проверки HTML (см. документацию по MDN на стороне клиента).
  • Внедрение сторонней библиотеки JavaScript для проверки.

Для статически отрисовываемых форм на сервере в конце 2025 года рассматривается новый механизм проверки на стороне клиента. Дополнительные сведения см. в статье "Создание форм, отрисованных сервером, с использованием Blazor проверки клиента без канала (dotnet/aspnetcore #51040)".

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