ASP.NET Core Blazor Formularvalidierung

Hinweis

Dies ist nicht die neueste Version dieses Artikels. Die aktuelle Version finden Sie in der .NET 10-Version dieses Artikels.

Warnung

Diese Version von ASP.NET Core wird nicht mehr unterstützt. Weitere Informationen finden Sie unter .NET und .NET Core Support Policy. Die aktuelle Version finden Sie in der .NET 10-Version dieses Artikels.

In diesem Artikel wird erläutert, wie Benutzereingaben in Blazor Formularen überprüft werden.

Für die meisten Formulare ist der einfachste und empfohlene Ansatz, dem Modell Validierungsattribute für Datenanmerkungen hinzuzufügen und eine DataAnnotationsValidator-Komponente in EditForm zu platzieren. Blazor unterstützt auch die benutzerdefinierte Überprüfung über die Formularkomponente EditContext, entweder direkt in der Formularkomponente oder in einer wiederverwendbaren Validatorkomponente.

Verwandte Artikel enthalten weitere Details:

Mit Datenanmerkungen validieren

Das folgende Modell verwendet RequiredAttribute und RangeAttribute:

Starship.cs:

using System.ComponentModel.DataAnnotations;

public class Starship
{
    [Required]
    public string? Identifier { get; set; }

    [Range(1, 10, ErrorMessage = "Accommodation must be between 1 and 10.")]
    public int MaximumAccommodation { get; set; }
}

Fügen Sie das Modell einem EditForm hinzu, schließen Sie DataAnnotationsValidator ein, und zeigen Sie Fehler mit ValidationMessage<TValue> oder ValidationSummary an. Der OnValidSubmit Rückruf wird nur aufgerufen, wenn die Überprüfung erfolgreich ist:

<EditForm Model="Model" OnValidSubmit="Submit">
    <DataAnnotationsValidator />
    <ValidationSummary />

    <p>
        <label>
            Identifier:
            <InputText @bind-Value="Model.Identifier" />
        </label>
        <ValidationMessage For="() => Model.Identifier" />
    </p>

    <p>
        <label>
            Maximum accommodation:
            <InputNumber @bind-Value="Model.MaximumAccommodation" />
        </label>
        <ValidationMessage For="() => Model.MaximumAccommodation" />
    </p>

    <button type="submit">Submit</button>
</EditForm>

@code {
    private Starship Model { get; } = new Starship();

    private void Submit()
    {
        // Process the valid form.
    }
}

Weisen Sie einem statischen SSR-Formular ein eindeutiges FormName zu und empfangen Sie das übermittelte Modell mit [SupplyParameterFromForm]:

<EditForm Model="Model" FormName="starship" OnValidSubmit="Submit">
    ...
</EditForm>

@code {
    [SupplyParameterFromForm]
    private Starship? Model { get; set; }

    protected override void OnInitialized() => Model ??= new();
}

Weitere Informationen zur Formularübermittlung und Modellbindung über Rendermodi hinweg finden Sie unter ASP.NET Core Blazor Formularübersicht und ASP.NET Core Blazor Formularbindung.

Ohne Komponente DataAnnotationsValidator nehmen Validierungsattribute für das Modell nicht an der Gültigkeitsprüfung des Formulars teil.

Wenn die Validierung durchgeführt wird

Blazor Führt die Feldüberprüfung und die Vollformularüberprüfung aus:

  • Die Feldüberprüfung wird nach einer Feldänderung ausgeführt. In einem interaktiven Formular tritt dies in .NET auf, während der Benutzer das Formular bearbeitet.
  • Die Validierung des gesamten Formulars erfolgt normalerweise, wenn EditForm das Absenden über OnValidSubmit oder OnInvalidSubmit verarbeitet. Ein OnSubmit-Handler übernimmt die Steuerung der Validierung, wie unter Formularübermittlung steuern beschrieben.

Ein statisches SSR-Formular kann Live-Browserfeedback mit ASP.NET Core Blazor clientseitiger Formularüberprüfung in statischem SSR bereitstellen. Das Formular wird beim Posten erneut autoritativ auf dem Server überprüft.

Ein statisches SSR-Formular wird bei der Übermittlung auf dem Server validiert und bietet zwischen Anfragen keine Live-Validierung der Felder.

Überprüfungsergebnisse, die ein Element identifizieren, sind diesem Feld zugeordnet. Ergebnisse ohne Namen eines Members werden dem Modell zugeordnet und in einer Validierungszusammenfassung statt in der ValidationMessage-Komponente eines Feldes angezeigt.

Konfigurieren der Überprüfung von Datenanmerkungen

DataAnnotationsValidator aktiviert immer die DataAnnotations-Überprüfung für das Formular. Rufen Sie die AddValidation Erweiterungsmethode in der Program Datei auf, um die vom Microsoft.Extensions.Validation Paket bereitgestellten erweiterten Überprüfungsfunktionen zu verwenden:

builder.Services.AddValidation();

Der AddValidation Aufruf registriert die Validierungsdienste des Pakets und aktiviert einen Quellgenerator, der Validierungsmetadaten für ermittelte Modelltypen erstellt. Das verfügbare Verhalten hängt davon ab, ob diese Metadaten das Modell des Formulars enthalten:

Configuration Behavior
Generierte Metadaten sind verfügbar. Überprüft geschachtelte Objekte und Sammlungen und unterstützt die Nachrichtenlokalisierung.
Generierte Metadaten sind nicht verfügbar. Überprüft die Eigenschaften der obersten Ebene, überprüft jedoch keine geschachtelten Objekte oder Auflistungen und verwendet nicht die Microsoft.Extensions.Validation Nachrichtenlokalisierungspipeline.
Configuration Behavior
Generierte Metadaten sind verfügbar. Überprüft geschachtelte Objekte und Auflistungen.
Generierte Metadaten sind nicht verfügbar. Überprüft nur Eigenschaften der obersten Ebene.

Die APIs ValidatableTypeAttribute und SkipValidationAttribute sind in .NET 10 experimentell. Ausführliche Informationen und verfügbare Problemumgehungen finden Sie unter Validierung in ASP.NET Core.

Deklarieren Sie bei Verwendung von Microsoft.Extensions.Validation Modelltypen in C#-Dateien (.cs) statt in Komponentendateien (Razor). Der Quellgenerator erstellt Validierungsmetadaten aus der C#-Quelle und kann keine Modelltypen enthalten, die in Razor Komponenten deklariert sind.

Informationen zu Konfigurationsanforderungen, Überprüfungsreihenfolge, benutzerdefinierten Regeln, geschachtelten Objektdiagrammen und generierten Metadaten finden Sie unter Überprüfung in ASP.NET Core.

Überprüfen geschachtelter Objektdiagramme

In .NET 9 oder früher validiert DataAnnotationsValidator Modelleigenschaften der obersten Ebene, jedoch keine Sammlungs- oder Eigenschaften komplexer Typen rekursiv. Verwenden Sie zur rekursiven Validierung ObjectGraphDataAnnotationsValidator und [ValidateComplexType] aus dem experimentellen Paket Microsoft.AspNetCore.Components.DataAnnotations.Validation:

<EditForm Model="Model" OnValidSubmit="Submit">
    <ObjectGraphDataAnnotationsValidator />
    ...
</EditForm>
public class Starship
{
    [ValidateComplexType]
    public ShipDescription Description { get; set; } =
        new ShipDescription();
}

Das Paket bleibt in diesen Frameworkversionen experimentell.

[CompareProperty]-Attribut

Verwenden Sie für .NET 5 oder früheren Versionen das experimentelle Paket ComparePropertyAttribute anstelle von CompareAttribute. ComparePropertyAttribute ordnet das Überprüfungsergebnis dem Feld während der Feld- und Vollformularüberprüfung konsistent zu.

Schreiben modellbasierter benutzerdefinierter Regeln

Wenn integrierte Attribute keine Regel ausdrücken können, verwenden Sie eine benutzerdefinierte ValidationAttribute oder IValidatableObject. Ausführliche Anleitungen finden Sie unter Validierung in ASP.NET Core.

Schreiben modellbasierter benutzerdefinierter Regeln

Wenn integrierte Attribute keine Regel ausdrücken können, verwenden Sie ein benutzerdefiniertes Überprüfungsattribut oder implementieren IValidatableObject. Beide laufen durch DataAnnotationsValidator.

Wenn Sie ein ValidationResult-Element aus einem benutzerdefinierten Attribut zurückgeben, schließen Sie den validierten Membernamen ein, damit das Ergebnis in der ValidationMessage-Komponente dieses Felds angezeigt werden kann.

Benutzerdefinierte Attribute können registrierte Dienste über GetService auflösen.

Validierung über EditContext hinzufügen

EditForm erstellt automatisch ein EditContext, wenn sein Model-Parameter zugewiesen wird. Wenn Sie Validierungs-APIs direkt verwenden möchten, erstellen Sie den Kontext selbst und weisen Sie ihn dem Parameter EditContext von EditForm zu. Weisen Sie nicht beides Model und EditContext demselben Formular zu.

Bei der benutzerdefinierten Überprüfung wird häufig Folgendes verwendet:

Das folgende interaktive Formularmuster fügt neben der Validierung von Datenanmerkungen eine Geschäftsregel auf Formularebene hinzu und überprüft die Regel erneut, wenn sich ein relevantes Feld ändert:

@implements IDisposable

<EditForm EditContext="editContext" OnValidSubmit="Submit">
    <DataAnnotationsValidator />
    <ValidationSummary />

    ...
</EditForm>

@code {
    private Starship Model { get; } = new Starship();
    private EditContext editContext = default!;
    private ValidationMessageStore messages = default!;

    protected override void OnInitialized()
    {
        editContext = new EditContext(Model);
        messages = new ValidationMessageStore(editContext);
        editContext.OnValidationRequested += ValidateBusinessRules;
        editContext.OnFieldChanged += ValidateChangedField;
    }

    private void ValidateBusinessRules(
        object? sender, ValidationRequestedEventArgs e)
    {
        messages.Clear();
        ValidateIdentifier();
        editContext.NotifyValidationStateChanged();
    }

    private void ValidateChangedField(
        object? sender, FieldChangedEventArgs e)
    {
        if (e.FieldIdentifier.FieldName != nameof(Starship.Identifier) &&
            e.FieldIdentifier.FieldName != nameof(Starship.MaximumAccommodation))
        {
            return;
        }

        messages.Clear(
            editContext.Field(nameof(Starship.Identifier)));
        ValidateIdentifier();
        editContext.NotifyValidationStateChanged();
    }

    private void ValidateIdentifier()
    {
        if (Model.MaximumAccommodation == 1 &&
            string.IsNullOrWhiteSpace(Model.Identifier))
        {
            messages.Add(
                editContext.Field(nameof(Starship.Identifier)),
                "An identifier is required for a single-occupant ship.");
        }
    }

    private void Submit()
    {
        // Process the valid form.
    }

    public void Dispose()
    {
        editContext.OnValidationRequested -= ValidateBusinessRules;
        editContext.OnFieldChanged -= ValidateChangedField;
    }
}

Ein OnFieldChanged Handler empfängt das geänderte Feld in e.FieldIdentifier. Löschen oder ersetzen Sie die betroffenen Nachrichten und rufen Sie NotifyValidationStateChanged an, wie das vorherige Beispiel zeigt.

Statisches SSR bietet keine .NET-Feldvalidierung in Echtzeit zwischen Anfragen.

Rufen Sie OnValidationRequested für die asynchrone Validierung des gesamten Formulars aus einem e.AddAsyncValidator-Handler heraus auf. Rufen Sie EditContext.RegisterAsyncFieldValidator für die asynchrone Feldvalidierung in einem interaktiven Formular in einem OnFieldChanged-Handler auf. Eine neue asynchrone Überprüfung für dasselbe Feld ersetzt und bricht die vorherige ab.

Informationen zu modellbasierten asynchronen Überprüfungsattributen finden Sie unter "Überprüfung" in ASP.NET Core. Eine vollständige wiederverwendbare Validatorkomponente finden Sie unter ASP.NET Core Blazor erweiterten Formularüberprüfung.

Eine wiederverwendbare Implementierung, die Ereignisabonnements und den zugehörigen Nachrichtenspeicher kapselt, finden Sie unter ASP.NET Core Blazor erweiterten Formularüberprüfung.

Anzeigen von Überprüfungsmeldungen

Dient ValidationMessage<TValue> zum Anzeigen von Nachrichten, die einem Feld zugeordnet sind:

<ValidationMessage For="() => Model.Identifier" />

Der For Ausdruck identifiziert das Feld anhand der Modellinstanz und -eigenschaft. Blazor stellt diese Identität mit einer FieldIdentifier dar, sodass Eigenschaften mit demselben Namen in verschiedenen Modellinstanzen als unterschiedliche Felder behandelt werden. Die Verwendung eines Ausdrucks anstelle einer Zeichenfolge ermöglicht es auch Refactoringtools, den Verweis auf die Eigenschaft zu aktualisieren.

Wird ValidationSummary verwendet, um Nachrichten für das Formular anzuzeigen:

<ValidationSummary />

Weisen Sie den Parameter der Zusammenfassung Model zu, um ihn auf Nachrichten zu beschränken, die einem bestimmten Modell zugeordnet sind:

<ValidationSummary Model="Model" />

Um aktuelle Nachrichten im Code zu überprüfen, rufen Sie GetValidationMessages auf:

var allMessages = editContext.GetValidationMessages();
var fieldMessages = editContext.GetValidationMessages(
    editContext.Field(nameof(Starship.Identifier)));

Diese Methoden lesen den aktuellen Überprüfungsstatus. Sie initiieren keine Überprüfung.

Darstellung der Validierung anpassen

Blazor wendet CSS-Klassen an, die den Feld- und Nachrichtenstatus darstellen:

Element Klassen
Input valid oder invalid, plus modified , nachdem der Benutzer das Feld bearbeitet hat
Überprüfungsmeldung validation-message
Überprüfungszusammenfassung validation-summary-errors oder validation-summary-valid

Eingabefelder mit asynchroner Feldvalidierung verwenden pending oder modified, optional mit invalid, anstelle von valid oder faulted, solange der entsprechende Zustand aktiv ist.

Die Blazor Projektvorlagen enthalten Stile für die gängigen Klassen „valid“ und „invalid“. Fügen Sie nach Bedarf Formatvorlagen für andere Klassen hinzu. ValidationMessage und ValidationSummary akzeptieren auch beliebige HTML-Attribute. Durch das Bereitstellen eines class Attributs wird die Standardklasse der Komponente ersetzt.

Um die Klassen zu ändern, die auf Eingabekomponenten angewendet werden, leiten Sie von FieldCssClassProvider.

using Microsoft.AspNetCore.Components.Forms;

public sealed class BootstrapFieldCssClassProvider : FieldCssClassProvider
{
    public override string GetFieldCssClass(
        EditContext editContext,
        in FieldIdentifier fieldIdentifier)
    {
        if (!editContext.IsModified(fieldIdentifier))
        {
            return string.Empty;
        }

        return editContext.IsValid(fieldIdentifier)
            ? "is-valid"
            : "is-invalid";
    }
}
using System.Linq;
using Microsoft.AspNetCore.Components.Forms;

public sealed class BootstrapFieldCssClassProvider : FieldCssClassProvider
{
    public override string GetFieldCssClass(
        EditContext editContext,
        in FieldIdentifier fieldIdentifier)
    {
        if (!editContext.IsModified(fieldIdentifier))
        {
            return string.Empty;
        }

        return editContext.GetValidationMessages(fieldIdentifier).Any()
            ? "is-invalid"
            : "is-valid";
    }
}

Ein Benutzerdefinierter FieldCssClassProvider bestimmt den vollständigen Klassenwert für jedes Feld. Wenn das Formular eine asynchrone Feldvalidierung verwendet, verarbeiten Sie IsValidationPending(fieldIdentifier) und IsValidationFaulted(fieldIdentifier) im Anbieter, wenn Klassen mit dem Status „Ausstehend“ oder „Fehlerhaft“ erforderlich sind.

Weisen Sie den Anbieter dem EditContext des Formulars zu:

editContext.SetFieldCssClassProvider(
    new BootstrapFieldCssClassProvider());

Für benutzerdefiniertes Eingabemarkup rufen Sie FieldCssClass auf, um die vom aktuellen Anbieter ausgewählte Klasse abzurufen.

Wenn einem EditForm ein Modell zugewiesen wird, erhält dessen untergeordneter Inhalt den generierten EditContext. Erfassen Sie den Kontext über den Context Parameter und den Aufruf FieldCssClass , um die Klassen des Felds auf das umgebende Markup anzuwenden:

<EditForm Model="Model" Context="editContext">
    <DataAnnotationsValidator />

    <div class="@editContext.FieldCssClass(
        () => Model.Identifier)">
        <InputText @bind-Value="Model.Identifier" />
        <ValidationMessage For="() => Model.Identifier" />
    </div>
</EditForm>

Reagieren auf den Überprüfungsstatus

EditContext macht den aktuellen Überprüfungsstatus verfügbar, ohne die Überprüfung zu initiieren.

  • Verwenden Sie IsModified() oder IsModified(field), um festzustellen, ob sich ein Feld oder ein beliebiges Feld im Formular geändert wurde.
  • Verwenden Sie GetValidationMessages() oder GetValidationMessages(field), um aktuelle Feld- oder Formularmeldungen zu prüfen.

Verwenden Sie IsValid(field), um zu ermitteln, ob ein Feld derzeit Validierungsmeldungen enthält.

Für ein Feld kann das Fehlen von Nachrichten mit !editContext.GetValidationMessages(field).Any() überprüft werden.

Im folgenden Beispiel wird die benutzerdefinierte Benutzeroberfläche erst angezeigt, nachdem ein Feld geändert und ungültig wurde:

@{
    var identifier = editContext.Field(nameof(Starship.Identifier));
}

@if (editContext.IsModified(identifier) &&
    !editContext.IsValid(identifier))
{
    <p>Correct the identifier before continuing.</p>
}
@{
    var identifier = editContext.Field(nameof(Starship.Identifier));
}

@if (editContext.IsModified(identifier) &&
    editContext.GetValidationMessages(identifier).Any())
{
    <p>Correct the identifier before continuing.</p>
}

Eingabekomponenten, ValidationMessageund ValidationSummary aktualisieren sich selbst, wenn sich der Überprüfungsstatus ändert. Eine Komponente, die andere UI für bedingte Validierung rendert, sollte OnValidationStateChanged abonnieren und StateHasChanged aufrufen:

private void HandleValidationStateChanged(
    object? sender, ValidationStateChangedEventArgs e) =>
    _ = InvokeAsync(StateHasChanged);

Melden Sie sich von OnValidationStateChanged ab, wenn die Komponente verworfen wird.

Verwenden Sie IsValidationPending(field) und IsValidationFaulted(field) für die asynchrone Feldvalidierung. Die parameterlosen Methoden beschreiben Überläufe auf Formularebene ValidateAsync und aggregieren nicht den Status jedes Felds.

Zu diesen Zuständen gehören auch asynchrone Vorgänge, die von DataAnnotationsValidator ausgeführt werden. Eine AsyncValidationAttribute auf eine Eigenschaft angewendete Eigenschaft verwendet den Feldzustand während der Feldüberprüfung, einschließlich der Standard pending - und faulted CSS-Klassen. Während ValidateAsync tragen asynchrone Attribute und IAsyncValidatableObject zum Status auf Formularebene bei, den die parameterlosen Methoden zurückgeben.

Live ausstehende Indikatoren erfordern einen interaktiven Renderingmodus. Während einer statischen SSR-Formularübermittlung wird die serverseitige Validierung abgeschlossen, bevor die Antwort gerendert wird.

Steuern der Formularübermittlung

EditForm stellt drei Callbacks für die Übermittlung bereit:

Callback Behavior
OnValidSubmit Wird ausgeführt, nachdem die automatische Überprüfung erfolgreich ausgeführt wurde.
OnInvalidSubmit Wird ausgeführt, nachdem die automatische Überprüfung fehlschlägt.
OnSubmit Gibt dem Handler die Kontrolle über Validierung und Absenden.

OnValidSubmit und OnInvalidSubmit kann zusammen verwendet werden. Kombinieren Sie OnSubmit mit keinem von beiden.

EditForm verwendet ValidateAsync vor dem Aufrufen OnValidSubmit oder OnInvalidSubmit, sodass es auf synchrone und asynchrone Validatoren wartet. Bei der Verarbeitung von OnSubmit rufen Sie vor der Verarbeitung des Formulars ValidateAsync auf:

<EditForm EditContext="editContext" OnSubmit="HandleSubmit">
    ...
</EditForm>

@code {
    private async Task HandleSubmit(EditContext editContext)
    {
        if (await editContext.ValidateAsync())
        {
            await SaveAsync();
        }
    }
}

Die synchrone Validate Methode ist in .NET 11 veraltet. Es wartet nicht auf die asynchrone Validierung und löst einen Fehler aus, wenn ein Handler versucht, asynchrone Vorgänge zu registrieren.

Bei interaktiven Formularen kann der ausstehende Status auf Formularebene verwendet werden, um das Absenden zu deaktivieren, während ValidateAsync ausgeführt wird:

<button type="submit" disabled="@editContext.IsValidationPending()">
    Save
</button>

Bei der Verarbeitung von OnSubmit rufen Sie vor der Verarbeitung des Formulars Validate auf:

<EditForm EditContext="editContext" OnSubmit="HandleSubmit">
    ...
</EditForm>

@code {
    private void HandleSubmit(EditContext editContext)
    {
        if (editContext.Validate())
        {
            Save();
        }
    }
}