składniki wejściowe ASP.NET Core Blazor

Uwaga

Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

Ważne

Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.

Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

W tym artykule opisano Blazorwbudowane składniki wejściowe.

Składniki wejściowe

Platforma Blazor udostępnia wbudowane składniki wejściowe do odbierania i weryfikowania danych wejściowych użytkownika. Wbudowane składniki wejściowe w poniższej tabeli są obsługiwane w elemecie EditForm z elementem EditContext.

Składniki w tabeli są również obsługiwane poza formularzem w Razor adiustacji składników. Dane wejściowe są weryfikowane po zmianie i przesłaniu formularza.

Składnik wejściowy Renderowane jako...
InputCheckbox <input type="checkbox">
InputDate<TValue> <input type="date">
InputFile <input type="file">
InputNumber<TValue> <input type="number">
InputRadio<TValue> <input type="radio">
InputRadioGroup<TValue> Grupa elementów podrzędnych InputRadio<TValue>
InputSelect<TValue> <select>
InputText <input>
InputTextArea <textarea>

Aby uzyskać więcej informacji na InputFile temat składnika, zobacz ASP.NET Core file uploads (Przekazywanie plików ASP.NET CoreBlazor).

Składnik wejściowy Renderowane jako...
InputCheckbox <input type="checkbox">
InputDate<TValue> <input type="date">
InputNumber<TValue> <input type="number">
InputSelect<TValue> <select>
InputText <input>
InputTextArea <textarea>

Uwaga

InputRadio<TValue> składniki i InputRadioGroup<TValue> są dostępne w ASP.NET Core 5.0 lub nowszym. Aby uzyskać więcej informacji, wybierz wersję 5.0 lub nowszą tego artykułu.

Wszystkie składniki wejściowe, w tym EditForm, obsługują dowolne atrybuty. Każdy atrybut, który nie pasuje do parametru składnika, jest dodawany do renderowanego elementu HTML.

Składniki wejściowe zapewniają domyślne zachowanie podczas sprawdzania poprawności po zmianie pola:

  • W przypadku składników wejściowych w formularzu z zachowaniem EditContextdomyślnej walidacji obejmuje aktualizowanie klasy CSS pola w celu odzwierciedlenia stanu pola jako prawidłowego lub nieprawidłowego przy użyciu stylu walidacji bazowego elementu HTML.
  • W przypadku kontrolek, które nie mają EditContextelementu , domyślna walidacja odzwierciedla prawidłowy lub nieprawidłowy stan, ale nie zapewnia stylu weryfikacji bazowego elementu HTML.

Niektóre składniki obejmują przydatną logikę analizowania. Na przykład InputDate<TValue> i InputNumber<TValue> obsłuż nieparzystne wartości bezpiecznie, rejestrując nieparzysłe wartości jako błędy walidacji. Typy, które mogą akceptować wartości null, obsługują również wartość null pola docelowego (na przykład int? dla liczby całkowitej dopuszczanej wartości null).

Aby uzyskać więcej informacji na InputFile temat składnika, zobacz ASP.NET Core file uploads (Przekazywanie plików ASP.NET CoreBlazor).

Przykładowy formularz

Następujący Starship typ, który jest używany w kilku przykładach tego artykułu i przykładach w innych artykułach dotyczących węzłów formularzy , definiuje zróżnicowany zestaw właściwości z adnotacjami danych:

  • Id jest wymagana, ponieważ jest oznaczona adnotacją za pomocą elementu RequiredAttribute. Id wymaga co najmniej jednego znaku, ale nie więcej niż 16 znaków przy użyciu znaku StringLengthAttribute.
  • Description jest opcjonalna, ponieważ nie jest oznaczona adnotacją za pomocą elementu RequiredAttribute.
  • Ciąg Classification jest wymagany.
  • Właściwość MaximumAccommodation jest domyślnie równa zero, ale wymaga wartości z jednej do 100 000 na wartość RangeAttribute.
  • IsValidatedDesign właściwość wymaga, aby właściwość miała wartość zgodną true z wybranym stanem, gdy właściwość jest powiązana z polem wyboru w interfejsie użytkownika (<input type="checkbox">).
  • ProductionDate jest elementem DateTime i wymaganym.

Starship.cs:

using System.ComponentModel.DataAnnotations;

namespace BlazorSample;

public class Starship
{
    [Required]
    [StringLength(16, ErrorMessage = "Identifier too long (16 character limit).")]
    public string? Id { get; set; }

    public string? Description { get; set; }

    [Required]
    public string? Classification { get; set; }

    [Range(1, 100000, ErrorMessage = "Accommodation invalid (1-100000).")]
    public int MaximumAccommodation { get; set; }

    [Required]
    [Range(typeof(bool), "true", "true", ErrorMessage = "Approval required.")]
    public bool IsValidatedDesign { get; set; }

    [Required]
    public DateTime ProductionDate { get; set; }
}
using System.ComponentModel.DataAnnotations;

public class Starship
{
    [Required]
    [StringLength(16, ErrorMessage = "Identifier too long (16 character limit).")]
    public string? Id { get; set; }

    public string? Description { get; set; }

    [Required]
    public string? Classification { get; set; }

    [Range(1, 100000, ErrorMessage = "Accommodation invalid (1-100000).")]
    public int MaximumAccommodation { get; set; }

    [Required]
    [Range(typeof(bool), "true", "true", 
        ErrorMessage = "This form disallows unapproved ships.")]
    public bool IsValidatedDesign { get; set; }

    [Required]
    public DateTime ProductionDate { get; set; }
}
using System.ComponentModel.DataAnnotations;

public class Starship
{
    [Required]
    [StringLength(16, ErrorMessage = "Identifier too long (16 character limit).")]
    public string? Id { get; set; }

    public string? Description { get; set; }

    [Required]
    public string? Classification { get; set; }

    [Range(1, 100000, ErrorMessage = "Accommodation invalid (1-100000).")]
    public int MaximumAccommodation { get; set; }

    [Required]
    [Range(typeof(bool), "true", "true", 
        ErrorMessage = "This form disallows unapproved ships.")]
    public bool IsValidatedDesign { get; set; }

    [Required]
    public DateTime ProductionDate { get; set; }
}
using System;
using System.ComponentModel.DataAnnotations;

public class Starship
{
    [Required]
    [StringLength(16, ErrorMessage = "Identifier too long (16 character limit).")]
    public string Id { get; set; }

    public string Description { get; set; }

    [Required]
    public string Classification { get; set; }

    [Range(1, 100000, ErrorMessage = "Accommodation invalid (1-100000).")]
    public int MaximumAccommodation { get; set; }

    [Required]
    [Range(typeof(bool), "true", "true", 
        ErrorMessage = "This form disallows unapproved ships.")]
    public bool IsValidatedDesign { get; set; }

    [Required]
    public DateTime ProductionDate { get; set; }
}
using System;
using System.ComponentModel.DataAnnotations;

public class Starship
{
    [Required]
    [StringLength(16, ErrorMessage = "Identifier too long (16 character limit).")]
    public string Id { get; set; }

    public string Description { get; set; }

    [Required]
    public string Classification { get; set; }

    [Range(1, 100000, ErrorMessage = "Accommodation invalid (1-100000).")]
    public int MaximumAccommodation { get; set; }

    [Required]
    [Range(typeof(bool), "true", "true", 
        ErrorMessage = "This form disallows unapproved ships.")]
    public bool IsValidatedDesign { get; set; }

    [Required]
    public DateTime ProductionDate { get; set; }
}

Poniższy formularz akceptuje i weryfikuje dane wejściowe użytkownika przy użyciu:

  • Właściwości i walidacja zdefiniowane w poprzednim Starship modelu.
  • Kilka wbudowanych składników wejściowych Blazor.

Po ustawieniu właściwości modelu klasyfikacji statku (Classification) jest zaznaczona opcja zgodna z modelem. Na przykład checked="@(Model!.Classification == "Exploration")" w przypadku klasyfikacji statku poszukiwawczego. Przyczyną jawnego ustawienia zaznaczonej opcji jest to, że wartość <select> elementu jest obecna tylko w przeglądarce. Jeśli formularz jest renderowany na serwerze po przesłaniu, każdy stan od klienta jest zastępowany stanem z serwera, co zwykle nie oznacza opcji jako zaznaczonej. Ustawiając zaznaczoną opcję z właściwości modelu, klasyfikacja zawsze odzwierciedla stan modelu. Spowoduje to zachowanie wyboru klasyfikacji między przesyłaniem formularzy, które powodują rerendering formularza na serwerze. W sytuacjach, gdy formularz nie jest rerendered na serwerze, na przykład gdy tryb renderowania serwera interaktywnego jest stosowany bezpośrednio do składnika, jawne przypisanie zaznaczonej opcji z modelu nie jest konieczne, ponieważ Blazor zachowuje stan elementu <select> na kliencie.

Starship3.razor:

@page "/starship-3"
@inject ILogger<Starship3> Logger

<h1>Starfleet Starship Database</h1>

<h2>New Ship Entry Form</h2>

<EditForm Model="Model" OnValidSubmit="Submit" FormName="Starship3">
    <DataAnnotationsValidator />
    <ValidationSummary />
    <div>
        <label>
            Identifier: 
            <InputText @bind-Value="Model!.Id" />
        </label>
    </div>
    <div>
        <label>
            Description (optional): 
            <InputTextArea @bind-Value="Model!.Description" />
        </label>
    </div>
    <div>
        <label>
            Primary Classification: 
            <InputSelect @bind-Value="Model!.Classification">
                <option value="">
                    Select classification ...
                </option>
                <option checked="@(Model!.Classification == "Exploration")" 
                    value="Exploration">
                    Exploration
                </option>
                <option checked="@(Model!.Classification == "Diplomacy")" 
                    value="Diplomacy">
                    Diplomacy
                </option>
                <option checked="@(Model!.Classification == "Defense")" 
                    value="Defense">
                    Defense
                </option>
            </InputSelect>
        </label>
    </div>
    <div>
        <label>
            Maximum Accommodation: 
            <InputNumber @bind-Value="Model!.MaximumAccommodation" />
        </label>
    </div>
    <div>
        <label>
            Engineering Approval: 
            <InputCheckbox @bind-Value="Model!.IsValidatedDesign" />
        </label>
    </div>
    <div>
        <label>
            Production Date: 
            <InputDate @bind-Value="Model!.ProductionDate" />
        </label>
    </div>
    <div>
        <button type="submit">Submit</button>
    </div>
</EditForm>

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

    protected override void OnInitialized() =>
        Model ??= new() { ProductionDate = DateTime.UtcNow };

    private void Submit()
    {
        Logger.LogInformation("Id = {Id} Description = {Description} " +
            "Classification = {Classification} MaximumAccommodation = " +
            "{MaximumAccommodation} IsValidatedDesign = " +
            "{IsValidatedDesign} ProductionDate = {ProductionDate}",
            Model?.Id, Model?.Description, Model?.Classification,
            Model?.MaximumAccommodation, Model?.IsValidatedDesign,
            Model?.ProductionDate);
    }
}
@page "/starship-3"
@inject ILogger<Starship3> Logger

<h1>Starfleet Starship Database</h1>

<h2>New Ship Entry Form</h2>

<EditForm Model="Model" OnValidSubmit="Submit">
    <DataAnnotationsValidator />
    <ValidationSummary />
    <div>
        <label>
            Identifier:
            <InputText @bind-Value="Model!.Id" />
        </label>
    </div>
    <div>
        <label>
            Description (optional):
            <InputTextArea @bind-Value="Model!.Description" />
        </label>
    </div>
    <div>
        <label>
            Primary Classification:
            <InputSelect @bind-Value="Model!.Classification">
                <option value="">Select classification ...</option>
                <option value="Exploration">Exploration</option>
                <option value="Diplomacy">Diplomacy</option>
                <option value="Defense">Defense</option>
            </InputSelect>
        </label>
    </div>
    <div>
        <label>
            Maximum Accommodation:
            <InputNumber @bind-Value="Model!.MaximumAccommodation" />
        </label>
    </div>
    <div>
        <label>
            Engineering Approval:
            <InputCheckbox @bind-Value="Model!.IsValidatedDesign" />
        </label>
    </div>
    <div>
        <label>
            Production Date:
            <InputDate @bind-Value="Model!.ProductionDate" />
        </label>
    </div>
    <div>
        <button type="submit">Submit</button>
    </div>
</EditForm>

@code {
    private Starship? Model { get; set; }

    protected override void OnInitialized() =>
        Model ??= new() { ProductionDate = DateTime.UtcNow };

    private void Submit()
    {
        Logger.LogInformation("Id = {Id} Description = {Description} " +
            "Classification = {Classification} MaximumAccommodation = " +
            "{MaximumAccommodation} IsValidatedDesign = " +
            "{IsValidatedDesign} ProductionDate = {ProductionDate}", 
            Model?.Id, Model?.Description, Model?.Classification, 
            Model?.MaximumAccommodation, Model?.IsValidatedDesign, 
            Model?.ProductionDate);
    }
}

Element EditForm w poprzednim przykładzie tworzy obiekt EditContext oparty na przypisanym Starship wystąpieniu (Model="...") i obsługuje prawidłowy formularz. W następnym przykładzie pokazano, jak przypisać element EditContext do formularza i zweryfikować, kiedy formularz zostanie przesłany.

W poniższym przykładzie:

  • Używana jest skrócona wersja wcześniejszego Starfleet Starship Database formularza (Starship3 składnika), która akceptuje tylko wartość identyfikatora statku starship. Inne Starship właściwości otrzymują prawidłowe wartości domyślne po utworzeniu Starship wystąpienia typu.
  • Metoda jest wykonywana Submit po wybraniu Submit przycisku.
  • Formularz jest weryfikowany przez wywołanie EditContext.Validate metody Submit .
  • Rejestrowanie jest wykonywane w zależności od wyniku weryfikacji.

Uwaga

Submit w następnym przykładzie przedstawiono jako metodę asynchroniczną, ponieważ przechowywanie wartości formularzy często używa wywołań asynchronicznych (await ...). Jeśli formularz jest używany w aplikacji testowej, jak pokazano, Submit jest uruchamiany synchronicznie. W celach testowych zignoruj następujące ostrzeżenie kompilacji:

Ta metoda asynchroniczna nie zawiera operatorów "await" i zostanie uruchomiona synchronicznie. ...

Starship4.razor:

@page "/starship-4"
@inject ILogger<Starship4> Logger

<EditForm EditContext="editContext" OnSubmit="Submit" FormName="Starship4">
    <DataAnnotationsValidator />
    <div>
        <label>
            Identifier: 
            <InputText @bind-Value="Model!.Id" />
        </label>
    </div>
    <div>
        <button type="submit">Submit</button>
    </div>
</EditForm>

@code {
    private EditContext? editContext;

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

    protected override void OnInitialized()
    {
        Model ??=
            new()
                {
                    Id = "NCC-1701",
                    Classification = "Exploration",
                    MaximumAccommodation = 150,
                    IsValidatedDesign = true,
                    ProductionDate = new DateTime(2245, 4, 11)
                };
        editContext = new(Model);
    }

    private async Task Submit()
    {
        if (editContext != null && editContext.Validate())
        {
            Logger.LogInformation("Submit called: Form is valid");

            // await ...
        }
        else
        {
            Logger.LogInformation("Submit called: Form is INVALID");
        }
    }
}
@page "/starship-4"
@inject ILogger<Starship4> Logger

<EditForm EditContext="editContext" OnSubmit="Submit">
    <DataAnnotationsValidator />
    <div>
        <label>
            Identifier:
            <InputText @bind-Value="Model!.Id" />
        </label>
    </div>
    <div>
        <button type="submit">Submit</button>
    </div>
</EditForm>

@code {
    private EditContext? editContext;

    private Starship Model { get; set; }

    protected override void OnInitialized()
    {
        Model ??= 
            new()
            {
                Id = "NCC-1701",
                Classification = "Exploration",
                MaximumAccommodation = 150,
                IsValidatedDesign = true,
                ProductionDate = new DateTime(2245, 4, 11)
            };
        editContext = new(Model);
    }

    private async Task Submit()
    {
        if (editContext != null && editContext.Validate())
        {
            Logger.LogInformation("Submit called: Form is valid");

            // await ...
        }
        else
        {
            Logger.LogInformation("Submit called: Form is INVALID");
        }
    }
}

Uwaga

EditContext Zmiana po przypisaniu nie jest obsługiwana.

Wybór wielu opcji ze składnikiem InputSelect

Powiązanie obsługuje multiple wybór opcji ze składnikiem InputSelect<TValue> . Zdarzenie @onchange udostępnia tablicę wybranych opcji za pośrednictwem argumentów zdarzeń (ChangeEventArgs). Wartość musi być powiązana z typem tablicy i powiązanie z typem tablicy sprawia, że multiple atrybut jest opcjonalny w tagu InputSelect<TValue> .

W poniższym przykładzie użytkownik musi wybrać co najmniej dwie klasyfikacje gwiazdek, ale nie więcej niż trzy klasyfikacje.

Starship5.razor:

@page "/starship-5"
@using System.ComponentModel.DataAnnotations
@inject ILogger<Starship5> Logger

<h1>Bind Multiple <code>InputSelect</code> Example</h1>

<EditForm EditContext="editContext" OnValidSubmit="Submit" FormName="Starship5">
    <DataAnnotationsValidator />
    <ValidationSummary />
    <div>
        <label>
            Select classifications (Minimum: 2, Maximum: 3):
            <InputSelect @bind-Value="Model!.SelectedClassification">
                <option value="@Classification.Exploration">Exploration</option>
                <option value="@Classification.Diplomacy">Diplomacy</option>
                <option value="@Classification.Defense">Defense</option>
                <option value="@Classification.Research">Research</option>
            </InputSelect>
        </label>
    </div>
    <div>
        <button type="submit">Submit</button>
    </div>
</EditForm>

@if (Model?.SelectedClassification?.Length > 0)
{
    <div>@string.Join(", ", Model.SelectedClassification)</div>
}

@code {
    private EditContext? editContext;

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

    protected override void OnInitialized()
    {
        Model = new();
        editContext = new(Model);
    }

    private void Submit()
    {
        Logger.LogInformation("Submit called: Processing the form");
    }

    private class Starship
    {
        [Required]
        [MinLength(2, ErrorMessage = "Select at least two classifications.")]
        [MaxLength(3, ErrorMessage = "Select no more than three classifications.")]
        public Classification[]? SelectedClassification { get; set; } =
            new[] { Classification.None };
    }

    private enum Classification { None, Exploration, Diplomacy, Defense, Research }
}
@page "/starship-5"
@using System.ComponentModel.DataAnnotations
@inject ILogger<Starship5> Logger

<h1>Bind Multiple <code>InputSelect</code> Example</h1>

<EditForm EditContext="editContext" OnValidSubmit="Submit">
    <DataAnnotationsValidator />
    <ValidationSummary />
    <div>
        <label>
            Select classifications (Minimum: 2, Maximum: 3):
            <InputSelect @bind-Value="Model!.SelectedClassification">
                <option value="@Classification.Exploration">Exploration</option>
                <option value="@Classification.Diplomacy">Diplomacy</option>
                <option value="@Classification.Defense">Defense</option>
                <option value="@Classification.Research">Research</option>
            </InputSelect>
        </label>
    </div>
    <div>
        <button type="submit">Submit</button>
    </div>
</EditForm>

@if (Model?.SelectedClassification?.Length > 0)
{
    <div>@string.Join(", ", Model.SelectedClassification)</div>
}

@code {
    private EditContext? editContext;

    private Starship? Model { get; set; }

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

    private void Submit()
    {
        Logger.LogInformation("Submit called: Processing the form");
    }

    private class Starship
    {
        [Required]
        [MinLength(2, ErrorMessage = "Select at least two classifications.")]
        [MaxLength(3, ErrorMessage = "Select no more than three classifications.")]
        public Classification[]? SelectedClassification { get; set; } =
            new[] { Classification.None };
    }

    private enum Classification { None, Exploration, Diplomacy, Defense, Research }
}

Aby uzyskać informacje na temat obsługi pustych ciągów i null wartości w powiązaniu danych, zobacz sekcję Binding options to C# object values (Opcje powiązania InputSelect z wartościami obiektów null języka C#).

Opcje powiązania InputSelect z wartościami obiektów null języka C#

Aby uzyskać informacje na temat obsługi pustych ciągów i null wartości w powiązaniu danych, zobacz ASP.NET Podstawowe Blazor powiązanie danych.

Obsługa nazw wyświetlanych

Kilka wbudowanych składników obsługuje nazwy wyświetlane z parametrem InputBase<TValue>.DisplayName .

W formularzu Starfleet Starship Database (Starship3 składnik) sekcji Przykładowy formularz data produkcji nowego statku starship nie określa nazwy wyświetlanej:

<label>
    Production Date:
    <InputDate @bind-Value="Model!.ProductionDate" />
</label>

Jeśli pole zawiera nieprawidłową datę przesłania formularza, komunikat o błędzie nie wyświetla przyjaznej nazwy. Nazwa pola "ProductionDate" nie zawiera spacji między znakami "Production" i "Date", gdy zostanie wyświetlona w podsumowaniu weryfikacji:

Pole ProductionDate musi być datą.

DisplayName Ustaw właściwość na przyjazną nazwę z spacją między wyrazami "Production" i "Date":

<label>
    Production Date:
    <InputDate @bind-Value="Model!.ProductionDate" 
        DisplayName="Production Date" />
</label>

Podsumowanie weryfikacji wyświetla przyjazną nazwę, gdy wartość pola jest nieprawidłowa:

Pole Data produkcji musi być datą.

Obsługa szablonu komunikatu o błędzie

InputDate<TValue> i InputNumber<TValue> obsługa szablonów komunikatów o błędach:

W formularzu Starfleet Starship Database (Starship3 składnik) sekcji Przykładowy formularz z przyjazną nazwą wyświetlaną przypisaną pole Production Date generuje komunikat o błędzie przy użyciu następującego domyślnego szablonu komunikatu o błędzie:

The {0} field must be a date.

Pozycja symbolu zastępczego {0} to miejsce, w którym wartość DisplayName właściwości jest wyświetlana, gdy błąd jest wyświetlany użytkownikowi.

<label>
    Production Date:
    <InputDate @bind-Value="Model!.ProductionDate" 
        DisplayName="Production Date" />
</label>

Pole Data produkcji musi być datą.

Przypisz szablon niestandardowy, aby ParsingErrorMessage udostępnić niestandardowy komunikat:

<label>
    Production Date:
    <InputDate @bind-Value="Model!.ProductionDate" 
        DisplayName="Production Date" 
        ParsingErrorMessage="The {0} field has an incorrect date value." />
</label>

Pole Data produkcji ma nieprawidłową wartość daty.

W formularzu Starfleet Starship Database (Starship3 składnik) sekcji Przykładowy formularz używa domyślnego szablonu komunikatu o błędzie:

The {0} field must be a date.

Pozycja symbolu zastępczego {0} to miejsce, w którym wartość DisplayName właściwości jest wyświetlana, gdy błąd jest wyświetlany użytkownikowi.

<label>
    Production Date:
    <InputDate @bind-Value="Model!.ProductionDate" />
</label>

Pole ProductionDate musi być datą.

Przypisz szablon niestandardowy, aby ParsingErrorMessage udostępnić niestandardowy komunikat:

<label>
    Production Date:
    <InputDate @bind-Value="Model!.ProductionDate" 
        ParsingErrorMessage="The {0} field has an incorrect date value." />
</label>

Pole ProductionDate ma nieprawidłową wartość daty.