Partilhar via


Visão geral dos formulários do ASP.NET Core Blazor

Observação

Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão .NET 9 deste artigo.

Advertência

Esta versão do ASP.NET Core não é mais suportada. Para obter mais informações, consulte a Política de suporte do .NET e .NET Core. Para a versão atual, consulte a versão .NET 9 deste artigo.

Importante

Estas informações referem-se a um produto de pré-lançamento que pode ser substancialmente modificado antes de ser lançado comercialmente. A Microsoft não oferece garantias, expressas ou implícitas, em relação às informações fornecidas aqui.

Para a versão atual, consulte a versão .NET 9 deste artigo.

Este artigo explica como usar formulários no Blazor.

Componentes de entrada e formulários

A estrutura Blazor suporta formulários e fornece componentes de entrada internos:

Observação

Os recursos de validação ASP.NET Core sem suporte são abordados na seção Recursos de validação sem suporte.

O namespace Microsoft.AspNetCore.Components.Forms fornece:

  • Classes para gerenciar elementos de formulário, estado e validação.
  • Acesso a componentes Input* integrados.

Um projeto criado a partir do modelo de projeto Blazor inclui o namespace no arquivo _Imports.razor do aplicativo, o que torna o namespace disponível para os componentes Razor do aplicativo.

Formulários HTML padrão são suportados. Crie um formulário usando a tag HTML <form> normal e especifique um manipulador de @onsubmit para lidar com a solicitação de formulário enviada.

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

No componente StarshipPlainForm anterior:

  • O formulário é renderizado onde o elemento <form> aparece. O formulário é nomeado com o atributo de diretiva @formname, que identifica exclusivamente o formulário para a estrutura Blazor.
  • O modelo é criado no bloco de @code do componente e mantido em uma propriedade pública (Model). O atributo [SupplyParameterFromForm] indica que o valor da propriedade associada deve ser fornecido a partir dos dados do formulário. Os dados na solicitação que correspondem ao nome da propriedade são vinculados à propriedade.
  • O componente InputText é um componente de entrada para edição de valores de cadeia de caracteres. O atributo de diretiva @bind-Value vincula a propriedade de modelo Model.Id à propriedade Value do componente InputText.
  • O método Submit é registado como um manipulador para o callback @onsubmit. O manipulador é chamado quando o formulário é enviado pelo usuário.

Importante

Sempre use o atributo de diretiva @formname com um nome de formulário distinto.

Blazor melhora a navegação na página e o tratamento de formulários, intercetando a solicitação para aplicar a resposta ao DOM existente, preservando o máximo possível do formulário renderizado. O aprimoramento evita a necessidade de carregar totalmente a página e fornece uma experiência de usuário muito mais suave, semelhante a um aplicativo de página única (SPA), embora o componente seja renderizado no servidor. Para obter mais informações, consulte ASP.NET Core Blazor roteamento e navegação.

de renderização de streaming é suportada para formulários HTML simples.

Observação

Os links de documentação para a fonte de referência do .NET geralmente carregam a ramificação padrão do repositório, que representa o desenvolvimento atual para a próxima versão do .NET. Para selecionar uma tag para uma versão específica, use a lista suspensa Alternar ramificações ou tags. Para obter mais informações, consulte Como selecionar uma marca de versão do código-fonte do ASP.NET Core (dotnet/AspNetCore.Docs #26205).

O exemplo anterior inclui suporte antifalsificação, incluindo um componente AntiforgeryToken no formulário. O suporte antifalsificação é explicado mais detalhadamente na seção Suporte antifalsificação deste artigo.

Para enviar um formulário com base em eventos DOM de outro elemento, por exemplo, oninput ou onblur, use JavaScript para enviar o formulário (submit (documentação MDN)).

Em vez de usar formulários simples em aplicativos Blazor, um formulário normalmente é definido com suporte a formulários internos do Blazorusando o componente EditForm da estrutura. O componente Razor a seguir demonstra elementos, componentes e código Razor típicos para renderizar um formulário da Web usando um componente EditForm.

Um formulário é definido usando o componente EditForm da estrutura Blazor. O componente Razor a seguir demonstra elementos, componentes e código Razor típicos para renderizar um formulário da Web usando um componente 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; }
    }
}

No componente Starship1 previamente mencionado:

  • O componente EditForm é renderizado onde o elemento <EditForm> aparece. O formulário é nomeado com a propriedade FormName, que identifica exclusivamente o formulário para a estrutura Blazor.
  • O modelo é criado no bloco de @code do componente e mantido em uma propriedade pública (Model). A propriedade é atribuída ao parâmetro EditForm.Model. O atributo [SupplyParameterFromForm] indica que o valor da propriedade associada deve ser fornecido a partir dos dados do formulário. Os dados na solicitação que correspondem ao nome da propriedade são vinculados à propriedade.
  • O componente InputText é um componente de entrada para editar valores de cadeia de caracteres. O atributo de diretiva @bind-Value vincula a propriedade do modelo Model.Id à propriedade Value do componente InputText.
  • O método Submit é registado como um gestor para o callback OnSubmit. O manipulador é chamado quando o formulário é enviado pelo usuário.

Importante

Sempre use a propriedade FormName com um nome de formulário exclusivo.

Blazor melhora a navegação na página e a manipulação de formulários dos componentes EditForm. Para obter mais informações, consulte ASP.NET Core Blazor roteamento e navegação.

de renderização de streaming é suportado para EditForm.

Observação

Os links de documentação para a fonte de referência do .NET geralmente carregam a ramificação padrão do repositório, que representa o desenvolvimento atual para a próxima versão do .NET. Para selecionar uma tag para uma versão específica, utilize a lista suspensa alternar ramificações ou tags. Para obter mais informações, consulte Como selecionar uma marca de versão do código-fonte do 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; }
    }
}

No componente Starship1 anterior:

  • O componente EditForm é renderizado onde o elemento <EditForm> aparece.
  • O modelo é criado no bloco de @code do componente e mantido em um campo privado (model). O campo é atribuído ao parâmetro EditForm.Model.
  • O componente InputText é um componente de entrada para edição de valores de cadeia de caracteres. O atributo de diretiva @bind-Value vincula a propriedade de modelo Model.Id à propriedade Value do componente InputText†.
  • O método Submit é registado como um manipulador para o callback OnSubmit. O manipulador é chamado quando o formulário é enviado pelo usuário.

†Para obter mais informações sobre vinculação de propriedade, consulte ASP.NET Core Blazor data binding.

No próximo exemplo, o componente anterior é modificado para criar o formulário no componente Starship2:

  • OnSubmit é substituído por OnValidSubmit, que processa o manipulador de eventos atribuído se o formulário for válido quando enviado pelo usuário.
  • Um componente ValidationSummary é adicionado para exibir mensagens de validação quando o formulário é inválido no envio do formulário.
  • O validador de anotações de dados (componenteDataAnnotationsValidator†) anexa suporte de validação usando anotações de dados:
    • Se o campo de formulário <input> for deixado em branco quando o botão Submit for selecionado, um erro aparecerá no resumo de validação (componenteValidationSummary) ("The Id field is required.") e Submitnão chamado.
    • Se o campo de formulário <input> contiver mais de dez caracteres quando o botão Submit for selecionado, um erro aparecerá no resumo de validação ("Id is too long."). Submit não se chama o.
    • Se o campo de formulário <input> contiver um valor válido quando o botão Submit for selecionado, Submit será chamado.

†O componente DataAnnotationsValidator é abordado na seção do componente Validador . O componente é abordado na seção dos componentes Resumo de Validação e Mensagem de Validação.

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

Manipular o envio de formulários

O EditForm fornece os seguintes callbacks para lidar com o envio de formulários:

  • Use OnValidSubmit para atribuir um manipulador de eventos a ser executado quando um formulário com campos válidos for enviado.
  • Use OnInvalidSubmit para atribuir um manipulador de eventos a ser executado quando um formulário com campos inválidos for enviado.
  • Use OnSubmit para atribuir um manipulador de eventos a ser executado, independentemente do status de validação dos campos de formulário. O formulário é validado chamando EditContext.Validate no método manipulador de eventos. Se Validate retornar true, o formulário é válido.

Limpar um formulário ou campo

Redefina um formulário limpando seu modelo de volta ao seu estado padrão, que pode ser executado dentro ou fora da marcação de um EditForm:

<button @onclick="ClearForm">Clear form</button>

...

private void ClearForm() => Model = new();

Como alternativa, use uma expressão Razor explícita:

<button @onclick="@(() => Model = new())">Clear form</button>

Redefina um campo limpando o valor do modelo de volta ao seu estado padrão:

<button @onclick="ResetId">Reset Identifier</button>

...

private void ResetId() => Model!.Id = string.Empty;

Como alternativa, use uma expressão Razor explícita:

<button @onclick="@(() => Model!.Id = string.Empty)">Reset Identifier</button>

Não há necessidade de chamar StateHasChanged nos exemplos anteriores porque StateHasChanged é chamado automaticamente pela estrutura Blazor para renderizar novamente o componente depois que um manipulador de eventos é invocado. Se um manipulador de eventos não for usado para invocar os métodos que limpam um formulário ou campo, o código do desenvolvedor deverá chamar StateHasChanged para renderizar novamente o componente.

Suporte antifalsificação

Os serviços antifalsificação são automaticamente adicionados às aplicações Blazor quando AddRazorComponents é chamado no ficheiro Program.

A aplicação usa o Antiforgery Middleware ao chamar UseAntiforgery no seu pipeline de processamento de pedidos no ficheiro Program. UseAntiforgery é chamado após a chamada para UseRouting. Se houver chamadas para UseRouting e UseEndpoints, a chamada para UseAntiforgery deve ir entre eles. Uma chamada para UseAntiforgery deve ser feita após chamadas para UseAuthentication e UseAuthorization.

O componente AntiforgeryToken renderiza um token antifalsificação como um campo oculto e o atributo [RequireAntiforgeryToken] habilita a proteção antifalsificação. Se uma verificação antifalsificação falhar, uma resposta 400 - Bad Request será lançada e o formulário não será processado.

Para formulários baseados em EditForm, o componente AntiforgeryToken e o atributo [RequireAntiforgeryToken] são adicionados automaticamente para fornecer proteção antifalsificação.

Para formulários baseados no elemento HTML <form>, adicione manualmente o componente AntiforgeryToken ao formulário:

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

Advertência

Para formulários baseados em EditForm ou no elemento HTML <form>, a proteção antifalsificação pode ser desativada passando required: false para o atributo [RequireAntiforgeryToken]. O exemplo a seguir desativa a proteção contra falsificação e não é recomendado para aplicações públicas:

@using Microsoft.AspNetCore.Antiforgery
@attribute [RequireAntiforgeryToken(required: false)]

Para obter mais informações, consulte ASP.NET Core Blazor authentication and authorization.

Atenuar os ataques de sobrepostagem

Formulários do lado do servidor renderizados estaticamente, como aqueles normalmente usados em componentes que criam e editam registros em um banco de dados com um modelo de formulário, podem ser vulneráveis a um ataque de de sobrepostagem , também conhecido como ataque de de atribuição em massa de . Um ataque de sobrepostagem ocorre quando um usuário mal-intencionado emite um formulário HTML POST para o servidor que processa dados para propriedades que não fazem parte do formulário renderizado e que o desenvolvedor não deseja permitir que os usuários modifiquem. O termo "overposting" significa literalmente que o utilizador mal-intencionado realizou um "POST" em excesso com o formulário sobre.

A sobrepostagem não é uma preocupação quando o modelo não inclui propriedades restritas para operações de criação e atualização. No entanto, é importante ter em mente a sobrepostagem ao trabalhar com formulários Blazor estáticos baseados em SSR que você mantém.

Para reduzir a sobrepostagem, recomendamos o uso de um modelo de exibição/objeto de transferência de dados (DTO) separado para o formulário e o banco de dados com operações de criação (inserção) e atualização. Quando o formulário é enviado, somente as propriedades do modelo de exibição/DTO são usadas pelo componente e pelo código C# para modificar o banco de dados. Todos os dados adicionais incluídos por um usuário mal-intencionado são descartados, para que o usuário mal-intencionado seja impedido de realizar um ataque de superpostagem.

Tratamento de formulários aprimorado

Aprimore o de navegação para solicitações POST de formulário com o parâmetro Enhance para formulários EditForm ou o atributo data-enhance para formulários HTML (<form>):

<EditForm ... Enhance ...>
    ...
</EditForm>
<form ... data-enhance ...>
    ...
</form>

Sem suporte: Não é possível definir a navegação aprimorada no elemento ancestral de um formulário para habilitar o tratamento aprimorado de formulários.

<div ... data-enhance ...>
    <form ...>
        <!-- NOT enhanced -->
    </form>
</div>

As publicações de formulário aprimoradas apenas funcionam com endpoints Blazor. A publicação de um formulário avançado em um ponto de extremidade nãoBlazor resulta em um erro.

Para desativar o tratamento avançado de formulários:

  • Para um EditForm, remova o parâmetro Enhance do elemento de formulário (ou defina-o como false: Enhance="false").
  • Para um HTML <form>, remova o atributo data-enhance do elemento de formulário (ou configurá-lo para false: data-enhance="false").

A navegação e o manuseamento de formulários melhorados do Blazorpodem reverter alterações dinâmicas no DOM se o conteúdo atualizado não fizer parte da renderização do servidor. Para preservar o conteúdo de um elemento, use o atributo data-permanent.

No exemplo a seguir, o conteúdo do elemento <div> é atualizado dinamicamente por um script quando a página é carregada:

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

Para desativar a navegação aprimorada e a manipulação de formulários globalmente, consulte ASP.NET Core Blazor startup.

Para obter orientação sobre como usar o evento enhancedload para ouvir atualizações de página aprimoradas, consulte ASP.NET Core Blazor roteamento e navegação.

Exemplos

Os exemplos não adotam o tratamento aprimorado de formulários para solicitações POST, mas todos os exemplos podem ser atualizados para adotar os recursos aprimorados seguindo as orientações na seção Tratamento de formulário aprimorado.

Os exemplos usam o operador tipificado por destino new, que foi introduzido com C# 9.0 e .NET 5. No exemplo a seguir, o tipo não é explicitamente declarado para o operador new:

public ShipDescription ShipDescription { get; set; } = new();

Se estiver usando C# 8.0 ou anterior (ASP.NET Core 3.1), modifique o código de exemplo para indicar o tipo para o operador new:

public ShipDescription ShipDescription { get; set; } = new ShipDescription();

Os componentes usam tipos de referência anuláveis (NRTs) e o compilador .NET executa a análise estática de estado nulo, ambos suportados no .NET 6 ou posterior. Para mais informações, consulte a secção sobre a migração do ASP.NET Core 5.0 para o 6.0.

Se estiver usando C# 9.0 ou anterior (.NET 5 ou anterior), remova as NRTs dos exemplos. Normalmente, isso envolve apenas a remoção dos pontos de interrogação (?) e pontos de exclamação (!) dos tipos no código de exemplo.

O SDK do .NET aplica diretivas globais using implícitas a projetos quando o alvo é .NET 6 ou posterior. Os exemplos usam um registrador para registrar informações sobre o processamento de formulários, mas não é necessário especificar uma diretiva @using para o namespace Microsoft.Extensions.Logging nos exemplos de componentes. Para mais informações, consulte os SDKs de projeto .NET: Diretivas de utilização implícitas.

Se estiver usando C# 9.0 ou anterior (.NET 5 ou anterior), adicione diretivas @using à parte superior do componente após a diretiva @page para qualquer API exigida pelo exemplo. Encontre namespaces de API por meio do Visual Studio (clique com o botão direito do mouse no objeto e selecione Peek Definition) ou do navegador de API .NET .

Para demonstrar como os formulários funcionam com anotações de dados e validação, os componentes de exemplo dependem de System.ComponentModel.DataAnnotations API. Se você quiser evitar uma linha extra de código em componentes que usam anotações de dados, disponibilize o namespace em todos os componentes do aplicativo com o arquivo de importações (_Imports.razor):

@using System.ComponentModel.DataAnnotations

Exemplos de formulário referem-se a aspetos do universo Star Trek. Star Trek é um copyright ©1966-2023 da CBS Studios e Paramount.

A validação do lado do cliente requer um circuito

Em Blazor Web Apps, a validação no lado do cliente requer um circuito de BlazorSignalR ativo. A validação do lado do cliente não está disponível para formulários em componentes que adotaram renderização estática do lado do servidor (SSR estático). Os formulários que adotam SSR estático são validados no servidor após o envio do formulário.

Recursos de validação não suportados

Todos os validadores internos de anotação de dados são suportados no Blazor com exceção do atributo de validação [Remote].

A validação do jQuery não é suportada em Razor componentes. Recomendamos qualquer uma das seguintes abordagens:

  • Siga as orientações em ASP.NET Core de validação de formulários Blazor para:
    • Validação do lado do servidor em um Blazor Web App que adota um modo de renderização interativo.
    • Validação do lado do cliente numa aplicação Blazor WebAssembly independente.
  • Use atributos de validação HTML nativos (consulte Validação de formulário do lado do cliente (documentação MDN)).
  • Adote uma biblioteca JavaScript de validação de terceiros.

Para formulários renderizados estaticamente no servidor, um novo mecanismo para validação do lado do cliente está sendo considerado para o .NET 10 no final de 2025. Para mais informações, veja Criar formulários renderizados no servidor com validação no cliente usando Blazor sem um circuito (dotnet/aspnetcore #51040).

Recursos adicionais