Dela via


Översikt över ASP.NET Core Blazor-formulär

Not

Det här är inte den senaste versionen av den här artikeln. Den aktuella versionen finns i den .NET 9-versionen av den här artikeln.

Varning

Den här versionen av ASP.NET Core stöds inte längre. Mer information finns i .NET och .NET Core Support Policy. För den nuvarande utgåvan, se den här artikelns .NET 9-version.

Viktig

Den här informationen gäller en förhandsversionsprodukt som kan ändras avsevärt innan den släpps kommersiellt. Microsoft lämnar inga garantier, uttryckliga eller underförstådda, med avseende på den information som tillhandahålls här.

För den aktuella versionen, se .NET 9-versionen av denna artikel.

Den här artikeln beskriver hur du använder formulär i Blazor.

Indatakomponenter och formulär

det Blazor ramverket stöder formulär och tillhandahåller inbyggda indatakomponenter:

Notera

Valideringsfunktioner som inte stöds ASP.NET Core beskrivs i avsnittet Valideringsfunktioner som inte stöds.

Det Microsoft.AspNetCore.Components.Forms namnområdet innehåller:

  • Klasser för att hantera formulärelement, tillstånd och validering.
  • Åtkomst till inbyggda Input* komponenter.

Ett projekt som skapats från Blazor projektmall innehåller namnområdet i appens _Imports.razor-fil, vilket gör namnområdet tillgängligt för appens Razor komponenter.

Standard-HTML-formulär stöds. Skapa ett formulär med den vanliga HTML-<form>-taggen och ange en @onsubmit-hanterare för hantering av den skickade formulärbegäran.

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

I den föregående StarshipPlainForm-komponenten:

  • Formuläret återges där elementet <form> visas. Formuläret namnges med direktivattributet @formname, som unikt identifierar formuläret till ramverket Blazor.
  • Modellen skapas i komponentens @code block och lagras i en offentlig egenskap (Model). Attributet [SupplyParameterFromForm] anger att värdet för den associerade egenskapen ska anges från formulärdata. Data i begäran som matchar egenskapens namn är bundna till egenskapen.
  • Komponenten InputText är en indatakomponent för redigering av strängvärden. Attributet @bind-Value-direktiv binder modellens egenskap Model.Id till egenskapen Value i InputText-komponenten.
  • Metoden Submit är registrerad som hanterare för @onsubmit återanrop. Hanteraren anropas när formuläret skickas av användaren.

Viktig

Använd alltid attributet @formname-direktiv med ett unikt formulärnamn.

Blazor förbättrar sidnavigeringen och formulärhanteringen genom att fånga upp begäran för att tillämpa svaret på den befintliga DOM, vilket bevarar så mycket av det renderade formuläret som möjligt. Förbättringen undviker behovet av att helt ladda sidan och ger en mycket smidigare användarupplevelse, ungefär som en ensidesapp (SPA), även när komponenten renderas på servern. Mer information finns i ASP.NET Core Blazor routning och navigering.

Återgivning av direktuppspelning stöds för vanliga HTML-formulär.

Anteckning

Dokumentationslänkar till .NET-referenskällan läser vanligtvis in lagringsplatsens standardgren, vilket representerar den aktuella utvecklingen för nästa version av .NET. Om du vill välja en tagg för en specifik version använder du listrutan Växla grenar eller taggar. Mer information finns i Så här väljer du en versionstagg för ASP.NET Core-källkod (dotnet/AspNetCore.Docs #26205).

Föregående exempel innehåller stöd för skydd mot förfalskning genom att inkludera en AntiforgeryToken-komponent i formuläret. Stöd för antiförfalskning förklaras ytterligare i avsnittet Antiförfalskningsstöd i den här artikeln.

Om du vill skicka ett formulär baserat på ett annat elements DOM-händelser, till exempel oninput eller onblur, använder du JavaScript för att skicka formuläret (submit (MDN-dokumentation)).

I stället för att använda vanliga formulär i Blazor appar definieras ett formulär vanligtvis med Blazorinbyggda formulärstöd med ramverkets EditForm komponent. Följande Razor-komponent visar typiska element, komponenter och Razor kod för att återge en webbformulär med hjälp av en EditForm komponent.

Ett formulär definieras med hjälp av Blazor ramverkets EditForm komponent. Följande Razor-komponent visar typiska element, komponenter och Razor kod för att återge en webbformulär med hjälp av en EditForm komponent.

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

I den föregående komponenten Starship1:

  • Komponenten EditForm återges där elementet <EditForm> visas. Formuläret namnges med egenskapen FormName, som unikt identifierar formuläret för det Blazor ramverket.
  • Modellen skapas i komponentens @code-block, och lagras i en publik egenskap (Model). Egenskapen tilldelas parametern EditForm.Model. Attributet [SupplyParameterFromForm] anger att värdet för den associerade egenskapen ska anges från formulärdata. Data i begäran som matchar egenskapens namn är bundna till egenskapen.
  • Komponenten InputText är en indatakomponent för redigering av strängvärden. Attributet @bind-Value-direktiv binder modellens egenskap Model.Id till InputText-komponentens egenskap Value.
  • Metoden Submit är registrerad som hanterare för OnSubmit återanrop. Hanteraren anropas när formuläret skickas av användaren.

Viktig

Använd alltid egenskapen FormName med ett unikt formulärnamn.

Blazor förbättrar sidnavigering och formulärhantering för EditForm komponenter. Mer information finns i ASP.NET Core Blazor routning och navigering.

för direktuppspelning stöds för EditForm.

Notis

Dokumentationslänkar till .NET-referenskällan läser vanligtvis in lagringsplatsens standardgren, vilket representerar den aktuella utvecklingen för nästa version av .NET. För att välja en tagg för en specifik version, använd rullgardinsmenyn Välj en gren eller tagg. Mer information finns i Så här väljer du en versionstagg för ASP.NET Core-källkod (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; }
    }
}

I den föregående Starship1-komponenten:

  • Komponenten EditForm återges där elementet <EditForm> visas.
  • Modellen skapas i komponentens @code block och lagras i ett privat fält (model). Fältet tilldelas parametern EditForm.Model.
  • Komponenten InputText är en indatakomponent för redigering av strängvärden. Attributet @bind-Value-direktiv binder egenskapen Model.Id modell till InputText komponentens egenskap Value†.
  • Metoden Submit är registrerad som hanterare för OnSubmit återanrop. Hanteraren anropas när formuläret skickas av användaren.

† Mer information om egenskapsbindning finns i ASP.NET Core Blazor databindning.

I nästa exempel ändras den föregående komponenten för att skapa formuläret i komponenten Starship2:

  • OnSubmit ersätts med OnValidSubmit, som bearbetar tilldelad händelsehanterare om formuläret är giltigt när det skickas av användaren.
  • En ValidationSummary komponent läggs till för att visa valideringsmeddelanden när formuläret är ogiltigt vid formuläröverföring.
  • Validatorn för dataanteckningar (DataAnnotationsValidator komponent†) bifogar valideringsstöd med hjälp av dataanteckningar:
    • Om formulärfältet <input> lämnas tomt när knappen Submit är vald visas ett fel i valideringssammanfattning (ValidationSummary-komponenten‡) ("The Id field is required.") och Submitinte anropas.
    • Om fältet <input> formulär innehåller fler än tio tecken när knappen Submit har valts visas ett fel i valideringssammanfattningen ("Id is too long."). Submit anropas inte.
    • Om fältet <input> formulär innehåller ett giltigt värde när knappen Submit är markerad anropas Submit.

†Komponenten DataAnnotationsValidator beskrivs i avsnittet Validator-komponenten. ‡Komponenten ValidationSummary beskrivs i komponenterna Valideringssammanfattning och valideringsmeddelande avsnittet.

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

Hantera formulärinsändning

I EditForm finns följande återanrop för att hantera formulärsändning:

  • Använd OnValidSubmit för att tilldela en händelsehanterare att köra när ett formulär med giltiga fält skickas.
  • Använd OnInvalidSubmit för att tilldela en händelsehanterare att köra när ett formulär med ogiltiga fält skickas.
  • Använd OnSubmit för att tilldela en händelsehanterare att köra oavsett formulärfältens valideringsstatus. Formuläret verifieras genom att anropa EditContext.Validate i händelsehanterarmetoden. Om Validate returnerar trueär formuläret giltigt.

Rensa ett formulär eller fält

Återställ ett formulär genom att återställa modellen till dess standardtillstånd, vilket kan göras inom eller utanför en EditForm:s taggning:

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

...

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

Alternativt kan du använda ett explicit Razor-uttryck:

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

Återställ ett fält genom att rensa modellvärdet tillbaka till standardtillståndet:

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

...

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

Du kan också använda ett explicit Razor uttryck:

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

Du behöver inte anropa StateHasChanged i föregående exempel eftersom StateHasChanged anropas automatiskt av Blazor-ramverket för att återskapa komponenten när en händelsehanterare anropas. Om en händelsehanterare inte används för att anropa de metoder som rensar ett formulär eller fält bör utvecklarkoden anropa StateHasChanged för att återskapa komponenten.

Stöd mot förfalskning

Antiforgery-tjänster läggs automatiskt till i apparna Blazor när AddRazorComponents anropas i filen Program.

Appen använder Antiforgery Middleware genom att anropa UseAntiforgery i begärans bearbetningsflöde i Program-filen. UseAntiforgery anropas efter anropet till UseRouting. Om det finns anrop till UseRouting och UseEndpointsmåste anropet till UseAntiforgery gå mellan dem. Ett anrop till UseAntiforgery måste göras efter anrop till UseAuthentication och UseAuthorization.

Komponenten AntiforgeryToken återger en antiforgerytoken som ett dolt fält, och attributet [RequireAntiforgeryToken] aktiverar skydd mot förfalskning. Om en antiforgery-kontroll misslyckas genereras ett 400 - Bad Request svar och formuläret bearbetas inte.

För formulär som baseras på EditFormläggs attributet AntiforgeryToken och [RequireAntiforgeryToken] automatiskt till för att ge skydd mot förfalskning.

För formulär som baseras på HTML-<form>-elementet lägger du manuellt till AntiforgeryToken-komponenten i formuläret:

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

Varning

För formulär som baseras på antingen EditForm eller HTML-<form>-elementet kan skydd mot förfalskning inaktiveras genom att required: false skickas till attributet [RequireAntiforgeryToken]. I följande exempel inaktiveras antiforgery och rekommenderas inte för offentliga appar:

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

Mer information finns i ASP.NET Core Blazor-autentisering och auktorisering.

Minska överpostningsattacker

Statiskt renderade formulär på serversidan, till exempel de som vanligtvis används i komponenter som skapar och redigerar poster i en databas med en formulärmodell, kan vara sårbara för en överpublicering attack, även kallat en masstilldelning attack. En överpubliceringsattack inträffar när en obehörig användare utfärdar ett HTML-formulär POST till servern som bearbetar data för egenskaper som inte ingår i det renderade formuläret och som utvecklaren inte vill tillåta användare att ändra. Termen "överpublicering" innebär bokstavligen att den skadliga användaren har över-postat med hjälp av formuläret.

Överpublicering är inte ett problem när modellen inte innehåller begränsade egenskaper för att skapa och uppdatera åtgärder. Det är dock viktigt att ha överpublicering i åtanke när du arbetar med statiska SSR-baserade Blazor formulär som du underhåller.

För att undvika överpublicering rekommenderar vi att du använder en separat vymodell/dataöverföringsobjekt (DTO) för formuläret och databasen med åtgärder för att skapa (infoga) och uppdatera. När formuläret skickas används endast egenskaperna för vymodellen/DTO:t av komponenten och C#-koden för att ändra databasen. Eventuella extra data som ingår av en obehörig användare ignoreras, så den skadliga användaren hindras från att utföra en överpostningsattack.

Förbättrad formulärhantering

Förbättra navigering för POST-formulärbegäranden med parametern Enhance för EditForm formulär eller data-enhance-attributet för HTML-formulär (<form>):

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

Stöds inte: Du kan inte ange förbättrad navigering i ett formulärs överordnade element för att möjliggöra förbättrad formulärhantering.

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

Förbättrade formulärposter fungerar bara med Blazor ändpunkter. Om du publicerar ett förbättrat formulär till en slutpunkt som inte ärBlazor resulterar det i ett fel.

Så här inaktiverar du förbättrad formulärhantering:

  • För en EditFormtar du bort parametern Enhance från formulärelementet (eller ställer in den på false: Enhance="false").
  • För en HTML-<form>tar du bort attributet data-enhance från formulärelementet (eller anger det till false: data-enhance="false").

Blazor:s förbättrade navigerings- och formulärhanteringar kan ångra dynamiska ändringar i DOM:en om det uppdaterade innehållet inte ingår i serverrenderingen. Om du vill bevara innehållet i ett element använder du attributet data-permanent.

I följande exempel uppdateras innehållet i <div>-elementet dynamiskt av ett skript när sidan läses in:

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

Information om hur du inaktiverar förbättrad navigering och formulärhantering globalt finns i ASP.NET Core Blazor start.

Information om hur du använder händelsen enhancedload för att lyssna efter förbättrade siduppdateringar finns i ASP.NET Core Blazor routning och navigering.

Exempel

Exempel använder inte förbättrad formulärhantering för POST-formulärbegäranden, men alla exempel kan uppdateras för att implementera de förbättrade funktionerna genom att följa riktlinjerna i avsnittet Förbättrad formulärhantering.

I exemplen används new operatorn, som introducerades med C# 9.0 och .NET 5. I följande exempel anges inte typen uttryckligen för new-operatorn:

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

Om du använder C# 8.0 eller tidigare (ASP.NET Core 3.1) ändrar du exempelkoden för att ange typen till operatorn new:

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

Komponenter använder null-referenstyper (NRT) och .NET-kompilatorn utför statisk analys med null-tillstånd, som båda stöds i .NET 6 eller senare. Mer information finns i Migrera från ASP.NET Core 5.0 till 6.0.

Om du använder C# 9.0 eller tidigare (.NET 5 eller tidigare) tar du bort NRT från exemplen. Vanligtvis innebär detta bara att ta bort frågetecken (?) och utropstecken (!) från typerna i exempelkoden.

.NET SDK tillämpar implicita globala using-direktiv på projekt när du riktar in dig på .NET 6 eller senare. I exemplen används ett loggverktyg för att logga information om formulärhantering, men det är inte nödvändigt att ange ett @using-direktiv för Microsoft.Extensions.Logging-namnutrymme i komponentexemplen. Mer information finns i .NET-projekt-SDK:er: Implicit användning av direktiv.

Om du använder C# 9.0 eller tidigare (.NET 5 eller tidigare) lägger du till @using-direktiv överst i komponenten efter @page-direktivet för alla API:er som krävs i exemplet. Leta upp API-namnområden via Visual Studio (högerklicka på objektet och välj Peek Definition) eller .NET API-webbläsaren.

För att visa hur formulär fungerar med dataanteckningar validering förlitar sig exempelkomponenter på System.ComponentModel.DataAnnotations API. Om du vill undvika en extra kodrad i komponenter som använder dataanteckningar gör du namnområdet tillgängligt i appens komponenter med importfilen (_Imports.razor):

@using System.ComponentModel.DataAnnotations

Formulärexempel refererar till aspekter av Star Trek universum. Star Trek är upphovsrättsskyddad ©1966-2023 av CBS Studios och Paramount.

Verifiering på klientsidan kräver en krets

I Blazor Web Appkräver validering på klientsidan en aktiv BlazorSignalR krets. Validering på klientsidan är inte tillgängligt för formulär i komponenter som har antagit statisk återgivning på serversidan (statisk SSR). Formulär som antar statisk SSR verifieras på servern när formuläret har skickats.

Valideringsfunktioner som inte stöds

Alla inbyggda valideringsverktyg för dataanteckningar stöds i Blazor, förutom valideringsattributet [Remote].

jQuery-validering stöds inte i Razor komponenter. Vi rekommenderar någon av följande metoder:

För statiskt renderade formulär på servern övervägs en ny mekanism för validering på klientsidan för .NET 10 i slutet av 2025. Mer information finns i Skapa serverrederade formulär med klientverifiering med hjälp av Blazor utan krets (dotnet/aspnetcore #51040).

Ytterligare resurser