ASP.NET Core Blazor validatie van formulieren aan clientzijde in statische SSR

In dit artikel wordt uitgelegd hoe Blazor u livevalidatie aan clientzijde toevoegt aan formulieren die gebruikmaken van statische server-side rendering (statische SSR). De browser valideert afzonderlijke velden wanneer de gebruiker deze bewerkt en valideert het volledige formulier voordat deze wordt verzonden. Als de controle aan de clientzijde is geslaagd, wordt het formulier verzonden en opnieuw gevalideerd op de server.

Formulieren die gebruikmaken van een interactieve weergavemodus, gebruiken niet de statische validatiefunctie aan de clientzijde van SSR, zoals beschreven in dit artikel. Zowel de validatie per veld als de validatie bij het indienen van het volledige formulier worden in .NET uitgevoerd via de EditContext van het formulier.

Hoe validatie aan clientzijde werkt

Wanneer een statisch SSR-formulier een DataAnnotationsValidator onderdeel bevat, Blazor geeft u de validatieregels van het formulier weer in de pagina en dwingt u deze af met behulp van JavaScript voordat het formulier wordt verzonden. De gebruiker ziet validatiefouten zonder een retour naar de server.

Validatie aan de clientzijde wordt automatisch geactiveerd wanneer aan de volgende voorwaarden wordt voldaan:

Voor de ingebouwde set validatiekenmerken is geen JavaScript-configuratie, extra pakket of serviceregistratie vereist. In de sectie Aangepaste validatieregels aan de clientzijde wordt beschreven hoe u ondersteuning kunt toevoegen voor aangepaste validatiekenmerken.

Important

Validatie aan de clientzijde is een verbetering van de gebruikerservaring, niet een definitieve validatiecontrole. Het kan worden overgeslagen door de JavaScript-uitvoering van de browser uit te schakelen of te wijzigen. Validatie aan de serverzijde wordt uitgevoerd nadat het formulier is geplaatst en gezaghebbend blijft. Vertrouw nooit op validatie aan de clientzijde om de gegevensintegriteit te beschermen.

Ondersteunde validatiekenmerken

De volgende System.ComponentModel.DataAnnotations kenmerken worden afgedwongen aan de clientzijde, die overeenkomen met het gedrag van gegevensaantekeningen aan de serverzijde:

Validatiekenmerken die niet worden weergegeven in deze lijst, inclusief aangepaste ValidationAttribute-afgeleide kenmerken, worden niet standaard afgedwongen aan de clientzijde. Ze blijven serverzijde uitvoeren nadat het formulier is verzonden. Als u een regel aan de clientzijde voor een aangepast kenmerk wilt opgeven, raadpleegt u de sectie Validatieregels aan de clientzijde .

Validatietijd

Een veld wordt gevalideerd wanneer de waarde wordt doorgevoerd. Voor tekstinvoer (<input> elementen) treedt dit op wanneer het veld de focus verliest. Selectievakjes en vervolgkeuzelijsten worden direct na selectie gevalideerd.

Nadat een veld een validatiefout heeft weergegeven of nadat het formulier ten minste één keer is verzonden, wordt het veld opnieuw gevalideerd op elke toetsaanslag, zodat correcties onmiddellijk worden doorgevoerd.

Als u het formulier indient, wordt elk bijgehouden veld gevalideerd. Als een veld ongeldig is, wordt de inzending geblokkeerd en wordt de focus verplaatst naar het eerste ongeldige veld.

Validatieberichten, lokalisatie en toegankelijkheid

Validatie aan de clientzijde gebruikt ValidationMessage<TValue> om berichten weer te geven voor afzonderlijke velden en ValidationSummary om berichten voor het hele formulier weer te geven. Dit is dezelfde manier waarop interactieve validatie berichten rapporteert aan gebruikers.

Wanneer validatielokalisatie is geconfigureerd, worden foutberichten gelokaliseerd op de server terwijl de pagina wordt weergegeven. Validatie aan de clientzijde geeft dus dezelfde gelokaliseerde tekenreeksen weer als de ervaring aan de serverzijde. Lokalisatie vereist Microsoft.Extensions.Validation. Zie Validatie in ASP.NET Core voor meer informatie.

ARIA-kenmerken voor invoerelementen en validatieberichtcontainers worden automatisch beheerd Blazor , zodat ondersteunende technologieën validatiefouten aankondigen zonder extra configuratie.

CSS-klassen voor validatiestatus

De validatie-engine aan de clientzijde past dezelfde CSS-klassen toe als Blazor's interactieve validatie, die worden weergegeven in de volgende tabel.

Element Klassen
Input valid of invalid, plus modified zodra de gebruiker het veld bewerkt
Validatiebericht validation-message
Validatieoverzicht validation-summary-errors of validation-summary-valid

Validatie aan de clientzijde roept ook de beperkingsvalidatie-API van de browser aan, dus de standaard CSS pseudoklassen :valid en :invalid weerspiegelen de huidige validatiestatus van elke invoer.

Afmelden voor validatie aan clientzijde

De functie kan op meerdere niveaus worden uitgeschakeld. Validatie aan de serverzijde wordt niet beïnvloed door een van de opties in deze sectie.

Afmelden voor één formulier

Stel de parameter DataAnnotationsValidator van het onderdeel DisableClientValidation in op true:

<DataAnnotationsValidator DisableClientValidation="true" />

Afmelden voor de hele app

Stel DisableClientValidation in op RazorComponentsServiceOptions wanneer Razor componentservices zijn geregistreerd in het bestand Program:

builder.Services.AddRazorComponents(options =>
{
    options.DisableClientValidation = true;
});

De globale optie heeft voorrang. Wanneer dit is ingesteld op true, genereren formulieren geen validatieregels aan de clientzijde.

Eén verzendknop uitschakelen

Gebruik het standaard HTML-kenmerkformnovalidate op de knop. Het formulier wordt geplaatst zonder controle aan de clientzijde en de validatie aan de serverzijde wordt nog steeds uitgevoerd na het bericht:

<button type="submit" formnovalidate>Save draft</button>

Dit kan worden gebruikt om een knop 'Concept opslaan' of 'Terug' te implementeren waarvoor het formulier niet volledig geldig hoeft te zijn om succesvol te kunnen verzenden.

Aangepaste validatieregels aan de clientzijde

Aangepaste validatiekenmerken blijven op de server worden uitgevoerd, maar hebben niet standaard een implementatie aan de clientzijde. Het afdwingen van een aangepaste regel in de browser bestaat uit twee stappen: het verzenden van de regel van het kenmerk .NET en het registreren van een overeenkomende JavaScript-validator. De implementatie aan de serverzijde blijft gezaghebbend.

De regel verzenden vanuit .NET

Implementeer IClientValidationRuleProvider op het validatiekenmerk en retourneer een of meer ClientValidationRule exemplaren. De regel Name identificeert de validator aan de clientzijde en Parameters levert waarden die de validator nodig heeft.

Het volgende StartsWithAttribute valideert aan serverzijde in IsValid en voegt een startswith clientzijdige regel toe met een parameter prefix:

using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Components.Forms;

namespace BlazorSample.Validation;

// A custom validation attribute that also contributes a client-side rule for static SSR
// forms. The rule name ('startswith') must match the validator registered on the client
// with Blazor.formValidation.addValidator.
public sealed class StartsWithAttribute : ValidationAttribute, IClientValidationRuleProvider
{
    private readonly string prefix;

    public StartsWithAttribute(string prefix)
    {
        this.prefix = prefix;
        ErrorMessage = $"The value must start with '{prefix}'.";
    }

    protected override ValidationResult? IsValid(object? value,
        ValidationContext validationContext)
    {
        // Leave empty values to RequiredAttribute, matching the client-side validator.
        if (value is not string text || text.Length == 0)
        {
            return ValidationResult.Success;
        }

        if (!text.StartsWith(prefix, StringComparison.Ordinal))
        {
            return new ValidationResult(ErrorMessage, [validationContext.MemberName!]);
        }

        return ValidationResult.Success;
    }

    public IEnumerable<ClientValidationRule> GetClientValidationRules()
    {
        yield return new ClientValidationRule(
            "startswith",
            new Dictionary<string, string> { ["prefix"] = prefix });
    }
}

Pas het kenmerk op de gebruikelijke manier toe op het model:

using System.ComponentModel.DataAnnotations;

namespace BlazorSample.Validation;

// Model for the static SSR client-side validation sample. The StartsWith attribute
// contributes a client-side rule enforced in the browser before the form is submitted.
public class ShipModel
{
    [Required]
    [StartsWith("NCC-")]
    public string? Registry { get; set; }
}

De JavaScript-validator registreren

Roep in JavaScript Blazor.formValidation.addValidator(name, validator) aan om een regelnaam te koppelen aan een validatiefunctie. De name moet exact overeenkomen ClientValidationRule.Name, inclusief behuizing. Registraties zijn appbreed en als u dezelfde naam opnieuw registreert, vervangt u de vorige validator.

Warning

Als er geen JavaScript-validator is geregistreerd voor de naam van een verzonden regel, wordt de regel overgeslagen in de browser. Validatie aan de serverzijde wordt nog steeds uitgevoerd wanneer het formulier wordt geplaatst.

Registreer aangepaste validators eenmaal vanuit de opstartcode van de app. Kies de registratielocatie op basis van hoe Blazor begint, zoals beschreven in de volgende tabel.

Blazor opstarten Registratielocatie
Automatisch opstarten (standaard) Een script direct na blazor.web.js
Handmatig Blazor.start() De voortzetting geretourneerd door Blazor.start()
Beide opstartstijlen De callback van een JavaScript-initializer afterWebStarted

Een JavaScript-initializer werkt met een van beide opstartstijlen. In een bestand met de naam {ASSEMBLY NAME}.lib.module.js in de map van wwwroot de app:

// A JavaScript initializer works with automatic or manual Blazor startup. The validation service
// is available when afterWebStarted runs, even if the current page contains no validated form.
export function afterWebStarted(blazor) {
  blazor.formValidation.addValidator('startswith', (context) => {
    const value = context.value;

    // An empty value is valid. Use [Required] to require a value.
    if (!value) {
      return { success: true };
    }

    return { success: value.startsWith(context.params.prefix) };
  });
}

Met automatisch opstarten kan in plaats daarvan direct na blazor.web.js een app-specifiek validatorscript worden geladen:

<script src="@Assets["_framework/blazor.web.js"]"></script>
<script src="@Assets["js/custom-validation.js"]"></script>

Het tweede script kan Blazor.formValidation.addValidator rechtstreeks aanroepen.

Met handmatig opstarten definieert u de registratie in een app-script:

function registerCustomValidators(blazor) {
  blazor.formValidation.addValidator('startswith', (context) => {
    const value = context.value;

    if (!value) {
      return { success: true };
    }

    return { success: value.startsWith(context.params.prefix) };
  });
}

// Automatic startup initializes formValidation before this script runs.
// Manual startup calls registerCustomValidators after Blazor.start completes.
if (Blazor.formValidation) {
  registerCustomValidators(Blazor);
}

Laad de scripts met automatisch opstarten uitgeschakeld en registreer de validators nadat Blazor.start() deze zijn voltooid:

<script src="@Assets["_framework/blazor.web.js"]" autostart="false"></script>
<script src="@Assets["js/custom-validation.js"]"></script>
<script>
    Blazor.start().then(() => {
        registerCustomValidators(Blazor);
    });
</script>

Important

Validators registreren vanuit de opstartcode van de app, niet van een pagina of formulieronderdeel. Een componentscript kan worden uitgevoerd voordat Blazor wordt gestart, en scripts die door verbeterde navigatie worden toegevoegd, worden niet uitgevoerd. Statische SSR-onderdelen kunnen ook niet worden gebruikt IJSRuntime omdat ze geen interactieve .NET runtime hebben.

JavaScript-validatorfuncties schrijven

De validator ontvangt een contextobject met de volgende leden, zoals wordt weergegeven in de volgende tabel.

Lid Beschrijving
value De huidige waarde van het veld als een tekenreeks of null/undefined wanneer er geen waarde is.
element Het gevalideerde element input, select of textarea.
params De regel is Parameters een tekenreekswoordenlijst.

Er wordt verwacht dat de validator { success: true } retourneert wanneer de waarde geldig is. Retourneer { success: false } om het door de server opgegeven bericht van de regel te gebruiken, of retourneer { success: false, message: '...' } om het bericht voor die oproep te overschrijven.

Lege waarden moeten normaal gesproken worden behandeld als geldig door andere regels dan required, zodat een optioneel veld leeg blijft terwijl er nog steeds waarden worden geverifieerd die worden opgegeven.

Implementeer dezelfde regelsemantiek in .NET en JavaScript, waaronder hoofdlettergevoeligheid, normalisatie en verwerking van lege waarden. Als de implementaties verschillen, kunnen de browser en de gezaghebbende validatie aan de serverzijde verschillende resultaten opleveren.

Formulier op aanvraag valideren

De Blazor.formValidation API maakt ook JavaScript-methoden beschikbaar voor het valideren op aanvraag, zoals in de volgende tabel wordt weergegeven.

Methode Beschrijving
validateField(element) Hiermee wordt één veldelement gevalideerd en wordt de foutweergave bijgewerkt. Geeft true terug indien geldig.
validateForm(form) Valideert elk bijgehouden veld in een formulier. Retourneert true wanneer alle velden geldig zijn.

Limitations

  • Regels aan de clientzijde worden alleen verzonden voor velden die zijn opgenomen in validatie aan de serverzijde. Zonder Microsoft.Extensions.Validationworden alleen modeleigenschappen op het hoogste niveau gevalideerd. Het valideren van geneste objecten en verzamelingen vereist dat de app AddValidation aanroept en dat het model wordt gedetecteerd. Zie Validatie in ASP.NET Core voor meer informatie. Houd er rekening mee dat deze beperking een opzettelijke functie is om fouten te voorkomen waarbij de gezaghebbende servervalidatie ontbreekt vanwege een onjuiste configuratie.
  • Invoer die is toegevoegd aan een bestaand formulier door een latere streaming-renderingupdate , ontvangt geen validatie aan de clientzijde. Een formulier dat in één gestreamde batch wordt geleverd, wordt normaal behandeld.
  • Alleen de kenmerken die worden vermeld in ondersteunde validatiekenmerken hebben ingebouwde implementaties aan de clientzijde. Een RangeAttribute met een operandtype dat niet numeriek is, wordt bijvoorbeeld alleen op de server afgedwongen. Voor andere kenmerken is een aangepaste validatieregel aan de clientzijde vereist.
  • Aangepaste JavaScript-validators zijn synchroon. Regels waarvoor een netwerkaanroep of ander asynchroon werk is vereist, moeten worden uitgevoerd op de server of asynchrone validatie gebruiken met een interactieve weergavemodus. Zie ASP.NET Core Blazor geavanceerde formuliervalidatie voor meer informatie.