Compartir vía


Información general de formularios de ASP.NET Core Blazor

Nota:

Esta no es la versión más reciente de este artículo. Para la versión actual, consulta la versión .NET 8 de este artículo.

Advertencia

Esta versión de ASP.NET Core ya no se admite. Para obtener más información, consulta la Directiva de soporte técnico de .NET y .NET Core. Para la versión actual, consulta la versión .NET 8 de este artículo.

Importante

Esta información hace referencia a un producto en versión preliminar, el cual puede sufrir importantes modificaciones antes de que se publique la versión comercial. Microsoft no proporciona ninguna garantía, expresa o implícita, con respecto a la información proporcionada aquí.

Para la versión actual, consulte la versión .NET 8 de este artículo.

En este artículo se explica cómo usar formularios en Blazor.

Componentes y formularios de entrada

El marco de Blazor admite formularios y proporciona componentes de entrada integrados:

Nota:

Las características de validación de ASP.NET Core no admitidas se tratan en la sección Características de validación no admitidas.

El espacio de nombres Microsoft.AspNetCore.Components.Forms proporciona:

  • Clases para administrar elementos de formulario, estado y validación.
  • Acceso a componentes de Input* integrados.

Un proyecto creado a partir de la plantilla de proyecto Blazor incluye el espacio de nombres en el archivo _Imports.razor de la aplicación, lo que hace que el espacio de nombres esté disponible para los componentes de Razor de la aplicación.

Se admiten formularios HTML estándar. Cree un formulario con la etiqueta HTML normal <form> y especifique un controlador de @onsubmit para controlar la solicitud de formulario 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; }
    }
}

En el componente StarshipPlainForm anterior:

  • El formulario se representa donde aparece el elemento <form>. El formulario recibe el nombre del atributo de directiva @formname, que identifica de forma única el formulario en el marco de trabajo Blazor.
  • El modelo se crea en el bloque @code del componente y se conserva en una propiedad pública (Model). El atributo [SupplyParameterFromForm] indica que el valor de la propiedad asociada debe proporcionarse a partir de los datos del formulario. Los datos de la solicitud que coinciden con el nombre de la propiedad están vinculados a la propiedad.
  • El componente InputText es un componente de entrada para editar valores de cadena. El atributo de directiva @bind-Value enlaza la propiedad del modelo Model.Id a la propiedad Value del componente InputText.
  • El método Submit se registra como un controlador para la devolución de llamada @onsubmit. Se llama al controlador cuando el usuario envía el formulario.

Importante

Use siempre el atributo de directiva @formname con un nombre de formulario único.

Blazor mejora la navegación de páginas y el control de formularios mediante la interceptación de la solicitud para aplicar la respuesta al DOM existente, conservando la mayor parte del formulario representado como sea posible. La mejora evita la necesidad de cargar completamente la página y proporciona una experiencia de usuario mucho más fluida, similar a una aplicación de página única (SPA), aunque el componente se representa en el servidor. Para más información, vea Enrutamiento y navegación de Blazor de ASP.NET Core.

La representación en streaming es compatible con formularios HTML simples.

Nota:

Los vínculos de la documentación al origen de referencia de .NET cargan normalmente la rama predeterminada del repositorio, que representa el desarrollo actual para la próxima versión de .NET. Para seleccionar una etiqueta de una versión específica, usa la lista desplegable Cambiar ramas o etiquetas. Para obtener más información, vea Procedimientos para seleccionar una etiqueta de versión de código fuente de ASP.NET Core (dotnet/AspNetCore.Docs #26205).

El ejemplo anterior incluye soporte antifalsificación mediante la inclusión de un componente de AntiforgeryToken en el formulario. El soporte antifalsificación se explica con más detalle en la sección Soporte antifalsificación de este artículo.

Para enviar un formulario basado en los eventos DOM de otro elemento, por ejemplo oninput o onblur, utilice JavaScript para enviar el formulario (submit(documentación MDN)).

En lugar de usar formularios simples en las aplicaciones Blazor, un formulario generalmente se define con el soporte de formulario integrado de Blazor usando el componente del marco EditForm. El componente siguiente Razor muestra elementos típicos, componentes y código Razor para representar un formulario web mediante un componente EditForm.

Un formulario se define mediante el componente EditForm del marco Blazor. El componente siguiente Razor muestra elementos típicos, componentes y código Razor para representar un formulario web mediante un 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; }
    }
}

En el componente Starship1 anterior:

  • El componente EditForm se representa donde aparezca el elemento <EditForm>. El formulario recibe el nombre del atributo de directiva @formname, que identifica de forma única el formulario en el marco de trabajo Blazor.
  • El modelo se crea en el bloque @code del componente y se conserva en una propiedad pública (Model). La propiedad se asigna al parámetro EditForm.Model. El atributo [SupplyParameterFromForm] indica que el valor de la propiedad asociada debe proporcionarse a partir de los datos del formulario. Los datos de la solicitud que coinciden con el nombre de la propiedad están vinculados a la propiedad.
  • El componente InputText es un componente de entrada para editar valores de cadena. El atributo de directiva @bind-Value enlaza la propiedad del modelo Model.Id a la propiedad Value del componente InputText.
  • El método Submit se registra como controlador para la devolución de llamada OnSubmit. Se llama al controlador cuando el usuario envía el formulario.

Importante

Use siempre el atributo de directiva @formname con un nombre de formulario único.

Blazor mejora la navegación de páginas y el control de formularios para los componentes EditForm. Para más información, vea Enrutamiento y navegación de Blazor de ASP.NET Core.

La representación en streaming es compatible con EditForm.

Nota:

Los vínculos de la documentación al origen de referencia de .NET cargan normalmente la rama predeterminada del repositorio, que representa el desarrollo actual para la próxima versión de .NET. Para seleccionar una etiqueta de una versión específica, usa la lista desplegable Cambiar ramas o etiquetas. Para obtener más información, vea Procedimientos para seleccionar una etiqueta de versión de código fuente de 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; }
    }
}

En el componente Starship1 anterior:

  • El componente EditForm se representa donde aparezca el elemento <EditForm>.
  • El modelo se crea en el bloque @code del componente y se conserva en un campo privado (model). El campo está asignado al parámetro EditForm.Model.
  • El componente InputText es un componente de entrada para editar valores de cadena. El atributo de la directiva @bind-Value enlaza la propiedad del modelo Model.Id a la propiedad Value del componente InputText†.
  • El método Submit se registra como controlador para la devolución de llamada OnSubmit. Se llama al controlador cuando el usuario envía el formulario.

†Para más información sobre el enlace de propiedades, vea Enlace de datos Blazor de ASP.NET Core.

En el ejemplo siguiente, se modifica el componente anterior para crear el formulario en el componente Starship2:

  • OnSubmit se reemplaza por OnValidSubmit, que procesa el controlador de eventos asignado si el formulario es válido cuando el usuario lo envía.
  • Se agrega un componente ValidationSummary para mostrar mensajes de validación cuando el formulario no es válido en el envío del formulario.
  • El validador de anotaciones de datos (componente† DataAnnotationsValidator) expone la compatibilidad con la validación mediante anotaciones de datos:
    • Si el campo de formulario <input> se deja en blanco cuando se selecciona el botón Submit, aparece un error en el resumen de validación (componente‡ ValidationSummary) ("The Id field is required.") y se llama a Submit.
    • Si el campo de formulario <input> contiene más de diez caracteres cuando se selecciona el botón Submit, aparece un error en el resumen de validación ("Id is too long."). Submit no se llama.
    • Si el campo de formulario <input> contiene un valor válido cuando se selecciona el botón Submit, se llama a Submit.

†El componente DataAnnotationsValidator se trata en la sección Componentes de validador. ‡El componente ValidationSummary se trata en la sección Resumen de validación y componentes de los mensajes de validación.

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

Control del envío de formularios

El componente EditForm proporciona las siguientes devoluciones de llamada para controlar el envío de formularios:

  • Use OnValidSubmit para asignar un controlador de eventos que se ejecute cuando se envía un formulario con campos válidos.
  • Use OnInvalidSubmit para asignar un controlador de eventos que se ejecute cuando se envía un formulario con campos no válidos.
  • Use OnSubmit para asignar un controlador de eventos que se ejecute independientemente del estado de validación de los campos de formulario. El formulario se valida mediante una llamada a EditContext.Validate en el método de controlador de eventos. Si Validate devuelve true, el formulario es válido.

Borrar un formulario o campo

Restablezca un formulario borrando su modelo y llevándolo de nuevo a su estado predeterminado, lo que se puede realizar dentro o fuera de un marcado de EditForm:

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

...

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

Como alternativa, use una expresión explícita Razor:

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

Restablezca un campo borrando su valor de modelo y llevándolo a su estado predeterminado:

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

...

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

Como alternativa, use una expresión explícita Razor:

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

No es necesario llamar a StateHasChanged en los ejemplos anteriores porque el marco Blazor llama automáticamente a StateHasChanged para volver a representar el componente después de invocar un controlador de eventos. Si no se usa un controlador de eventos para invocar los métodos que borran un formulario o campo, el código de desarrollador debe llamar a StateHasChanged para volver a representar el componente.

Compatibilidad con antiforgería

Los servicios antifalsificación se agregan automáticamente a las aplicaciones Blazor cuando se llama a AddRazorComponents en el archivo Program.

La aplicación usa el middleware antifalsificación llamando a UseAntiforgery en su canalización de procesamiento de solicitudes en el archivo Program. UseAntiforgery se llama después de la llamada a UseRouting. Si hay llamadas a UseRouting y UseEndpoints, la llamada a UseAntiforgery debe ir entre ellas. Se debe realizar una llamada a UseAntiforgery después de las llamadas a UseAuthentication y UseAuthorization.

El componente AntiforgeryToken representa un token antiforgería como un campo oculto y el atributo [RequireAntiforgeryToken] habilita la protección antiforgería. Si se produce un error en una comprobación antiforgería, se produce una respuesta 400 - Bad Request y no se procesa el formulario.

En el caso de los formularios basados en EditForm, el componente AntiforgeryToken y el atributo [RequireAntiforgeryToken] se agregan automáticamente para proporcionar protección antifalsificación.

Para formularios basados en el elemento HTML <form>, agregue manualmente el componente AntiforgeryToken al formulario:

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

Advertencia

Para los formularios basados en EditForm o en el elemento <form> de HTML, se puede deshabilitar la protección antiforgería pasando required: false al atributo [RequireAntiforgeryToken] . En el ejemplo siguiente se deshabilita la antiforgería y no se recomienda para las aplicaciones públicas:

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

Para obtener más información, consulte Autenticación y autorización Blazor de ASP.NET Core.

Mitigación de ataques por publicación excesiva

Los formularios en el lado servidor representados estáticamente, como los que se usan normalmente en componentes que crean y editan registros en una base de datos con un modelo de formulario, pueden ser vulnerables a un ataque por publicación excesiva, también conocido como ataque de asignación masiva. Un ataque por publicación excesiva se produce cuando un usuario malintencionado emite una instrucción POST de formulario HTML en el servidor que procesa los datos de las propiedades que no forman parte del formulario representado y que el desarrollador no desea permitir que los usuarios modifiquen. El término "publicación excesiva" significa literalmente que el usuario malintencionado publica en exceso en el formulario.

La publicación excesiva no es un problema si el modelo no incluye propiedades restringidas para las operaciones de creación y actualización. Sin embargo, es importante tener en cuenta la publicación excesiva al trabajar con los formularios de Blazor basados en SSR estáticos que se mantienen.

Para mitigar la publicación excesiva, se recomienda usar un objeto de transferencia de datos (DTO) o modelo de vista independiente para el formulario y la base de datos con operaciones de creación (inserción) y actualización. Cuando se envía el formulario, el componente y el código de C# solo usan las propiedades del modelo de vista o DTO para modificar la base de datos. Los datos adicionales incluidos por un usuario malintencionado se descartan, lo cual impide que el usuario malintencionado realice un ataque por publicación excesiva.

Control mejorado de formularios

Mejore la navegación para solicitudes POST de formularios con el parámetro Enhance para formularios EditForm o el atributo data-enhance para formularios HTML (<form>):

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

No admitido: No se puede establecer la navegación mejorada en el elemento antepasado de un formulario para habilitar el control mejorado de formularios.

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

Los envíos de formularios mejorados solo funcionan con Blazor puntos de conexión. La publicación de un formulario mejorado en un noBlazor punto de conexión produce un error.

Para deshabilitar el control mejorado de formularios:

  • Para un EditForm, elimine el parámetro Enhance del elemento del formulario (o configúrelo a false: Enhance="false").
  • Para un HTML <form>, elimina el atributo data-enhance del elemento formulario (o configúralo a false: data-enhance="false").

Blazor navegación mejorada y el control de formularios pueden deshacer cambios dinámicos en el DOM si el contenido actualizado no forma parte de la renderización del servidor. Para conservar el contenido de un elemento, utiliza el atributo data-permanent.

En el siguiente ejemplo, el contenido del elemento <div> se actualiza dinámicamente mediante un script cuando se carga la página:

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

Para deshabilitar la navegación mejorada y la administración de formularios de forma global, consulte Inicio de BlazorASP.NET Core.

Para obtener orientación sobre el uso del event enhancedloado para escuchar actualizaciones de páginas mejoradas, consulte Enrutamiento y navegación de ASP.NET Core Blazor.

Ejemplos

Los ejemplos no adoptan la administración de formularios mejorada para las solicitudes POST de formularios, pero todos los ejemplos pueden actualizarse para adoptar las funciones mejoradas siguiendo las instrucciones de la sección Control mejorado de formularios.

Los ejemplos usan el operador new con tipo de destino, que se introdujo con C# 9.0 y .NET 5. En el ejemplo siguiente, el tipo no se indica explícitamente para el operador new:

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

Si usa C# 8.0 o una versión anterior (ASP.NET Core 3.1), modifique el código de ejemplo para indicar el tipo al operador new:

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

Los componentes usan tipos de referencia que aceptan valores NULL (NRT) y el compilador de .NET realiza análisis estáticos de estado NULL, ambos están admitidos en .NET 6 o versiones posteriores. Para más información, vea Migración de ASP.NET Core 5.0 a 6.0.

Si usa C# 9.0 o versiones anteriores (.NET 5 o versiones anteriores), quite los NRT de los ejemplos. Normalmente, esto simplemente implica quitar los signos de interrogación (?) y los signos de exclamación (!) de los tipos del código de ejemplo.

El SDK de .NET aplica directivas using globales e implícitas a los proyectos cuando tienen como destino .NET 6 o posterior. Los ejemplos usan un registrador para registrar información sobre el procesamiento de formularios, pero no es necesario especificar una directiva @using para el espacio de nombres Microsoft.Extensions.Logging en los ejemplos de componentes. Para saber más, consulte SDK de proyectos de .NET: directivas de uso implícito.

Si usa C# 9.0 o versiones anteriores (.NET 5 o versiones anteriores), agregue directivas @using a la parte superior del componente después de la directiva @page para cualquier API requerida por el ejemplo. Busque espacios de nombres de API a través de Visual Studio (haga clic con el botón derecho en el objeto y seleccione Ver definición) o el explorador de API de .NET.

Para demostrar cómo funcionan los formularios con anotaciones de datos validación, los componentes de ejemplo se basan en la API de System.ComponentModel.DataAnnotations. Si desea evitar una línea de código adicional en componentes que usan anotaciones de datos, haga que el espacio de nombres esté disponible en todos los componentes de la aplicación con el archivo de importaciones (_Imports.razor):

@using System.ComponentModel.DataAnnotations

Ejemplos de formulario hacen referencia a aspectos del universo de Star Trek . Star Trek está protegido por copyright ©1966-2023 de CBS Studios y Paramount.

La validación del lado cliente requiere un circuito

En Blazor Web App, la validación del lado cliente requiere un circuito activo BlazorSignalR. La validación del lado cliente no está disponible para formularios en componentes que han adoptado la representación estática del lado servidor (SSR estático). Los formularios que adoptan SSR estático se validan en el servidor después de enviar el formulario.

Características de validación no admitidas

Todos los validadores integrados de anotación de datos se admiten en Blazor, excepto el atributo de validación [Remote].

La validación de jQuery no se admite en Razor componentes. Se recomienda cualquiera de los enfoques siguientes:

  • Siga las instrucciones de ASP.NET validación de formularios core Blazor para:
    • Validación del lado servidor en un Blazor Web App que adopta un modo de representación interactiva.
    • Validación del lado cliente en una aplicación de ensamblado web independiente Blazor .
  • Use atributos de validación HTML nativos (consulte Validación de formularios del lado cliente (documentación de MDN)).
  • Adopte una biblioteca de JavaScript de validación de terceros.

En el caso de los formularios representados estáticamente en el servidor, se está considerando un nuevo mecanismo para la validación del lado cliente para .NET 10 a finales de 2025. Para obtener más información, consulte Creación de formularios representados por el servidor con validación de cliente mediante Blazor sin un circuito (dotnet/aspnetcore #51040).

Recursos adicionales