Bagikan melalui


komponen input ASP.NET Core Blazor

Catatan

Ini bukan versi terbaru dari artikel ini. Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.

Peringatan

Versi ASP.NET Core ini tidak lagi didukung. Untuk informasi selengkapnya, lihat Kebijakan Dukungan .NET dan .NET Core. Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.

Penting

Informasi ini berkaitan dengan produk pra-rilis yang mungkin dimodifikasi secara substansial sebelum dirilis secara komersial. Microsoft tidak memberikan jaminan, tersirat maupun tersurat, sehubungan dengan informasi yang diberikan di sini.

Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.

Artikel ini menjelaskan Blazorkomponen input bawaan.

Komponen input

Blazor Kerangka kerja menyediakan komponen input bawaan untuk menerima dan memvalidasi input pengguna. Komponen input bawaan dalam tabel berikut ini didukung dalam EditForm dengan EditContext.

Komponen dalam tabel juga didukung di luar formulir dalam Razor markup komponen. Input divalidasi saat diubah dan kapan formulir dikirimkan.

Komponen input Dirender sebagai...
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> Grup anak InputRadio<TValue>
InputSelect<TValue> <select>
InputText <input>
InputTextArea <textarea>

Untuk informasi selengkapnya tentang InputFile komponen, lihat unggahan file ASP.NET CoreBlazor.

Komponen input Dirender sebagai...
InputCheckbox <input type="checkbox">
InputDate<TValue> <input type="date">
InputNumber<TValue> <input type="number">
InputSelect<TValue> <select>
InputText <input>
InputTextArea <textarea>

Catatan

InputRadio<TValue> komponen dan InputRadioGroup<TValue> tersedia di ASP.NET Core 5.0 atau yang lebih baru. Untuk informasi selengkapnya, pilih versi 5.0 atau yang lebih baru dari artikel ini.

Semua komponen input, termasuk EditForm, mendukung atribut arbitrer. Atribut apa pun yang tidak cocok dengan parameter komponen ditambahkan ke elemen HTML yang dirender.

Komponen input menyediakan perilaku default untuk memvalidasi saat bidang diubah:

  • Untuk komponen input dalam formulir dengan EditContext, perilaku validasi default termasuk memperbarui kelas CSS bidang untuk mencerminkan status bidang sebagai valid atau tidak valid dengan gaya validasi elemen HTML yang mendasar.
  • Untuk kontrol yang tidak memiliki EditContext, validasi default mencerminkan status valid atau tidak valid tetapi tidak memberikan gaya validasi ke elemen HTML yang mendasar.

Beberapa komponen termasuk logika penguraian yang berguna. Misalnya, InputDate<TValue> dan InputNumber<TValue> menangani nilai yang tidak dapat dipisahkan dengan anggun dengan mendaftarkan nilai yang tidak dapat dipisahkan sebagai kesalahan validasi. Jenis yang dapat menerima nilai null juga mendukung nullability bidang target (misalnya, int? untuk bilangan bulat null).

Untuk informasi selengkapnya tentang InputFile komponen, lihat unggahan file ASP.NET CoreBlazor.

Formulir contoh

Jenis berikutStarship, yang digunakan dalam beberapa contoh dan contoh artikel ini di artikel node Formulir lainnya, menentukan serangkaian properti yang beragam dengan anotasi data:

  • Id diperlukan karena dianomasikan dengan RequiredAttribute. Id membutuhkan nilai setidaknya satu karakter tetapi tidak lebih dari 16 karakter menggunakan StringLengthAttribute.
  • Description bersifat opsional karena tidak dianomasi dengan RequiredAttribute.
  • Classification diperlukan.
  • Properti MaximumAccommodation default ke nol tetapi memerlukan nilai dari satu hingga 100.000 per nilai .RangeAttribute
  • IsValidatedDesign mengharuskan properti memiliki true nilai, yang cocok dengan status yang dipilih saat properti terikat ke kotak centang di UI (<input type="checkbox">).
  • ProductionDate adalah dan DateTime diperlukan.

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

Formulir berikut menerima dan memvalidasi input pengguna menggunakan:

  • Properti dan validasi yang ditentukan dalam model sebelumnya Starship .
  • BlazorBeberapa komponen input bawaan.

Saat properti model untuk klasifikasi kapal (Classification) diatur, opsi yang cocok dengan model dicentang. Misalnya, checked="@(Model!.Classification == "Exploration")" untuk klasifikasi kapal eksplorasi. Alasan untuk secara eksplisit mengatur opsi yang dicentang adalah bahwa nilai <select> elemen hanya ada di browser. Jika formulir dirender di server setelah dikirimkan, status apa pun dari klien ditimpa dengan status dari server, yang biasanya tidak menandai opsi sebagai dicentang. Dengan mengatur opsi yang dicentang dari properti model, klasifikasi selalu mencerminkan status model. Ini mempertahankan pemilihan klasifikasi di seluruh pengiriman formulir yang menghasilkan penyajian formulir di server. Dalam situasi di mana formulir tidak dirender di server, seperti ketika mode render Server Interaktif diterapkan langsung ke komponen, penetapan eksplisit dari opsi yang dicentang dari model tidak diperlukan karena Blazor mempertahankan status untuk <select> elemen pada klien.

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

EditForm Dalam contoh sebelumnya membuat berdasarkan instans yang EditContext ditetapkan Starship (Model="...") dan menangani formulir yang valid. Contoh berikutnya menunjukkan cara menetapkan EditContext ke formulir dan memvalidasi kapan formulir dikirimkan.

Dalam contoh berikut:

  • Versi singkat dari formulir (Starship3komponen) sebelumnya Starfleet Starship Database digunakan yang hanya menerima nilai untuk Id starship. Properti lain Starship menerima nilai default yang valid saat instans jenis Starship dibuat.
  • Metode Submit dijalankan ketika tombol Submit dipilih.
  • Formulir divalidasi dengan memanggil EditContext.Validate dalam Submit metode .
  • Pengelogan dijalankan tergantung pada hasil validasi.

Catatan

Submit dalam contoh berikutnya ditunjukkan sebagai metode asinkron karena menyimpan nilai formulir sering menggunakan panggilan asinkron (await ...). Jika formulir digunakan dalam aplikasi pengujian seperti yang ditunjukkan, Submit hanya berjalan secara sinkron. Untuk tujuan pengujian, abaikan peringatan build berikut:

Metode asinkron ini tidak memiliki operator 'menunggu' dan akan berjalan secara sinkron. ...

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

Catatan

Mengubah EditContext setelah ditetapkan tidak didukung.

Pilihan beberapa opsi dengan InputSelect komponen

Pengikatan mendukung multiple pilihan opsi dengan InputSelect<TValue> komponen. Kejadian ini @onchange menyediakan array opsi yang dipilih melalui argumen peristiwa (ChangeEventArgs). Nilai harus terikat ke jenis array, dan pengikatan ke jenis array membuat multiple atribut opsional pada InputSelect<TValue> tag.

Dalam contoh berikut, pengguna harus memilih setidaknya dua klasifikasi starship tetapi tidak lebih dari tiga klasifikasi.

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

Untuk informasi tentang bagaimana string dan null nilai kosong ditangani dalam pengikatan data, lihat bagian Opsi pengikatan InputSelect ke nilai objek null C# .

Opsi pengikatan InputSelect ke nilai objek null C#

Untuk informasi tentang bagaimana string dan null nilai kosong ditangani dalam pengikatan data, lihat pengikatan data ASP.NET CoreBlazor.

Dukungan nama tampilan

Beberapa komponen bawaan mendukung nama tampilan dengan InputBase<TValue>.DisplayName parameter .

Starfleet Starship Database Dalam formulir (Starship3 komponen) dari bagian Formulir contoh, tanggal produksi starship baru tidak menentukan nama tampilan:

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

Jika bidang berisi tanggal yang tidak valid saat formulir dikirimkan, pesan kesalahan tidak menampilkan nama yang mudah diingat. Nama bidang, "ProductionDate" tidak memiliki spasi antara "Production" dan "Date" saat muncul di ringkasan validasi:

Bidang ProductionDate harus berupa tanggal.

Atur DisplayName properti ke nama yang mudah diingat dengan spasi antara kata "Production" dan "Date":

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

Ringkasan validasi menampilkan nama yang mudah diingat ketika nilai bidang tidak valid:

Bidang Tanggal Produksi harus berupa tanggal.

Dukungan templat pesan kesalahan

InputDate<TValue> dan InputNumber<TValue> mendukung templat pesan kesalahan:

Starfleet Starship Database Dalam formulir (Starship3 komponen) dari bagian Formulir contoh dengan nama tampilan ramah yang ditetapkan, Production Date bidang menghasilkan pesan kesalahan menggunakan templat pesan kesalahan default berikut:

The {0} field must be a date.

Posisi {0} tempat penampung adalah tempat nilai DisplayName properti muncul saat kesalahan ditampilkan kepada pengguna.

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

Bidang Tanggal Produksi harus berupa tanggal.

Tetapkan templat kustom untuk ParsingErrorMessage menyediakan pesan kustom:

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

Bidang Tanggal Produksi memiliki nilai tanggal yang salah.

Starfleet Starship Database Dalam formulir (Starship3 komponen) dari bagian Formulir contoh menggunakan templat pesan kesalahan default:

The {0} field must be a date.

Posisi {0} tempat penampung adalah tempat nilai DisplayName properti muncul saat kesalahan ditampilkan kepada pengguna.

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

Bidang ProductionDate harus berupa tanggal.

Tetapkan templat kustom untuk ParsingErrorMessage menyediakan pesan kustom:

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

Bidang ProductionDate memiliki nilai tanggal yang salah.