EditForm · binding · validering

Forms med EditForm

Indsaml brugerinput med EditForm, InputText, DataAnnotations og ValidationMessage — struktureret OOP før I poster søgninger mod OpgaverAPI.

Læringsmål

Hvornår EditForm? Når brugeren indsender data I vil validere før HTTP — søgning, opret favorit, indtast API-nøgle-label — så I undgår unødige 400/404 mod OpgaverAPI.

Tjek dig selv før du går videre

  • Du kan binde EditForm til en model med DataAnnotations.
  • Du ved hvornår ValidationMessage vises.
  • Du har testet form-lab med ugyldig input.

I Blazor samler I formularer med <EditForm>. Den kræver en model og callbacks som OnValidSubmit / OnInvalidSubmit. Det tvinger jer til tydelige typer — godt når I senere mapper til API-DTO’er.

Mini-form (min. 2 tegn)

Skriv et Pokémon-navn og submit — labben simulerer client-validering før API-kald.

@page "/soeg-pokemon"
@using System.ComponentModel.DataAnnotations
@inject IPokemonService Pokemon

<EditForm Model="form" OnValidSubmit="HandleValidSubmit" OnInvalidSubmit="OnBad">
  <DataAnnotationsValidator />
  <ValidationSummary />

  <div class="mb-3">
    <label for="q">Navn</label>
    <InputText id="q" class="form-control" @bind-Value="form.Query" />
    <ValidationMessage For="@(() => form.Query)" />
  </div>

  <button type="submit" class="btn primary">Hent fra API</button>
</EditForm>

@if (results?.Count > 0)
{
  <ul>@foreach (var p in results) { <li>@p.Name</li> }</ul>
}

@code {
  private SearchForm form = new();
  List<PokemonDto>? results;

  private async Task HandleValidSubmit()
  {
    results = await Pokemon.SearchByNameAsync(form.Query);
  }

  private void OnBad() => results = null;

  public class SearchForm
  {
    [Required(ErrorMessage = "Navn er påkrævet")]
    [MinLength(2, ErrorMessage = "Mindst 2 tegn")]
    public string Query { get; set; } = "";
  }
}

DataAnnotations

Attributter på properties: [Required], [MinLength], [Range], [EmailAddress], [RegularExpression]. DataAnnotationsValidator kobler dem til EditContext.

public class ApiKeyForm
{
  [Required, StringLength(64, MinimumLength = 8)]
  public string KeyLabel { get; set; } = "";
}

Hvornår hvilken annotation? [Required] på tom submit. [MinLength] på søgestrenge. [Range] på limit i pagineret Pokémon-hentning. Server-side validering på API erstatter ikke client UX — begge lag er ideelle.

ValidationMessage vs Summary

Hvornår ValidationMessage For=? Altid ved felt med brugerinput — For="@(() => form.Query)" binder fejl til netop det input. Summary alene skjuler hvilket felt der fejler i lange LoL-formularer.

<ValidationMessage For="@(() => form.ChampionName)" class="text-danger" />

EditContext (avanceret)

Når I skal validere på tværs af felter (fx «slutdato efter startdato»), opret I EditContext manuelt og lytter på OnValidationRequested.

var editContext = new EditContext(model);
<EditForm EditContext="editContext" OnValidSubmit="Submit">
  ...
</EditForm>

Hvornår manuel EditContext? Custom validators, «bekræft sletning» checkbox der påvirker hele form, eller dynamiske felter. Standard EditForm + Model dækker 80 % af skoleprojekter.

Faldgrube: At bruge plain <input> uden InputText / @bind korrekt — EditContext opdateres ikke, og validering kører på gammel state. Brug Blazor input-komponenter eller @bind med korrekt event.

Model vs API-DTO

Form-model behøver ikke matche JSON 1:1. Map i OnValidSubmit til det DTO I sender med POST — fx opret favorit-Pokémon med kun name og id.

private async Task HandleValidSubmit()
{
    var dto = new CreateFavoriteDto(form.ChampionName.Trim(), form.Region);
    await Lol.PostFavoriteAsync(dto); // API-DTO kan have andre navne end form-klassen
}

Elev-fejl → symptom → fix: POST med form-klassen direkte — symptom: 400 Bad Request. Fix: separat API-DTO med JSON-kompatible navne.

Quiz 1

Hvornår kører OnValidSubmit?

Quiz 2

Hvilken komponent viser fejl for ét felt?

Hvorfor det betyder noget: EditForm + annotations giver samme validering i UI og API — vigtigt ved POST til OpgaverAPI.

Sådan fejler det i praksis: Submit uden EditContext — knappen sender ugyldig LoL-data; brugeren ser ingen fejl.

Mini-opgave

EditForm «ny LoL-favorit»: Required champion-navn, MaxLength 40. Valid submit logger model — samme mønster som form-lab.

Quiz 3

Client-side validering af Required på champion-navn?

Læs hos Microsoft

Prøv med API

  • Søgeformular mod /go/pokemon?name=... eller Countries.
  • Tilføj validering så tom streng ikke sender unødigt HTTP-kald.
16476 #516475 #416475 #5

Baseret på MAGS Blazor-wiki og Microsoft Learn — Blazor.