Menandai Pembantu dalam formulir di ASP.NET Core

Oleh Rick Anderson, N. Taylor Mullen, Dave Paquette, dan Jerrie Pelser

Dokumen ini menunjukkan bekerja dengan Formulir dan elemen HTML yang umum digunakan pada Formulir. Elemen Formulir HTML menyediakan mekanisme utama yang digunakan aplikasi web untuk memposting kembali data ke server. Sebagian besar dokumen ini menjelaskan Pembantu Tag dan bagaimana mereka dapat membantu Anda membuat formulir HTML yang kuat secara produktif. Kami sarankan Anda membaca Pengenalan Pembantu Tag sebelum Anda membaca dokumen ini.

Dalam banyak kasus, Pembantu HTML menyediakan pendekatan alternatif untuk Pembantu Tag tertentu, tetapi penting untuk mengenali bahwa Pembantu Tag tidak mengganti Pembantu HTML dan tidak ada Pembantu Tag untuk setiap Pembantu HTML. Ketika alternatif Pembantu HTML ada, itu disebutkan.

Pembantu Tag Formulir

Pembantu Tag Formulir:

  • Menghasilkan nilai atribut HTML <FORM>action untuk tindakan pengontrol MVC atau rute bernama

  • Menghasilkan Token Verifikasi Permintaan tersembunyi untuk mencegah pemalsuan permintaan lintas situs (saat digunakan dengan [ValidateAntiForgeryToken] atribut dalam metode tindakan POS HTTP)

  • asp-route-<Parameter Name> Menyediakan atribut , di mana <Parameter Name> ditambahkan ke nilai rute. Parameter routeValues untuk Html.BeginForm dan Html.BeginRouteForm menyediakan fungsionalitas serupa.

  • Memiliki alternatif Html.BeginForm Pembantu HTML dan Html.BeginRouteForm

Sampel:

<form asp-controller="Demo" asp-action="Register" method="post">
    <!-- Input and Submit elements -->
</form>

Pembantu Tag Formulir di atas menghasilkan HTML berikut:

<form method="post" action="/Demo/Register">
    <!-- Input and Submit elements -->
    <input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>

Runtime MVC menghasilkan action nilai atribut dari atribut asp-controller Form Tag Helper dan asp-action. Pembantu Tag Formulir juga menghasilkan Token Verifikasi Permintaan tersembunyi untuk mencegah pemalsuan permintaan lintas situs (saat digunakan dengan [ValidateAntiForgeryToken] atribut dalam metode tindakan Pos HTTP). Melindungi Formulir HTML murni dari pemalsuan permintaan lintas situs sulit, Pembantu Tag Formulir menyediakan layanan ini untuk Anda.

Menggunakan rute bernama

Atribut asp-route Tag Helper juga dapat menghasilkan markup untuk atribut HTML action . Aplikasi dengan rute bernama register dapat menggunakan markup berikut untuk halaman pendaftaran:

<form asp-route="register" method="post">
    <!-- Input and Submit elements -->
</form>

Banyak tampilan di folder Views/Account (dihasilkan saat Anda membuat aplikasi web baru dengan Akun Pengguna Individual) berisi atribut asp-route-returnurl :

<form asp-controller="Account" asp-action="Login"
     asp-route-returnurl="@ViewData["ReturnUrl"]"
     method="post" class="form-horizontal" role="form">

Catatan

Dengan templat bawaan, returnUrl hanya diisi secara otomatis ketika Anda mencoba mengakses sumber daya yang diotorisasi tetapi tidak diautentikasi atau diotorisasi. Saat Anda mencoba akses yang tidak sah, middleware keamanan akan mengarahkan Anda ke halaman masuk dengan returnUrl set.

Pembantu Tag Tindakan Formulir

Pembantu Tag Tindakan Formulir menghasilkan formaction atribut pada yang dihasilkan <button ...> atau <input type="image" ...> tag. Atribut formaction mengontrol tempat formulir mengirimkan datanya. Ini mengikat elemen <input> elemen jenis image dan <tombol> . Pembantu Tag Tindakan Formulir memungkinkan penggunaan beberapa atribut AnchorTagHelperasp- untuk mengontrol tautan apa yang formaction dihasilkan untuk elemen yang sesuai.

Atribut AnchorTagHelper yang didukung untuk mengontrol nilai formaction:

Atribut Deskripsi
pengontrol asp Nama pengontrol.
asp-action Nama metode tindakan.
asp-area Nama area.
asp-page Nama Razor halaman.
asp-page-handler Nama Razor handler halaman.
asp-route Nama rute.
asp-route-{value} Satu nilai rute URL. Misalnya, asp-route-id="1234".
asp-all-route-data Semua nilai rute.
fragmen asp Fragmen URL.

Kirim ke contoh pengontrol

Markup berikut mengirimkan formulir ke Index tindakan HomeController saat input atau tombol dipilih:

<form method="post">
    <button asp-controller="Home" asp-action="Index">Click Me</button>
    <input type="image" src="..." alt="Or Click Me" asp-controller="Home" 
                                asp-action="Index">
</form>

Markup sebelumnya menghasilkan HTML berikut:

<form method="post">
    <button formaction="/Home">Click Me</button>
    <input type="image" src="..." alt="Or Click Me" formaction="/Home">
</form>

Kirim ke contoh halaman

Markup berikut mengirimkan formulir ke AboutRazor Halaman:

<form method="post">
    <button asp-page="About">Click Me</button>
    <input type="image" src="..." alt="Or Click Me" asp-page="About">
</form>

Markup sebelumnya menghasilkan HTML berikut:

<form method="post">
    <button formaction="/About">Click Me</button>
    <input type="image" src="..." alt="Or Click Me" formaction="/About">
</form>

Kirim ke contoh rute

/Home/Test Pertimbangkan titik akhir:

public class HomeController : Controller
{
    [Route("/Home/Test", Name = "Custom")]
    public string Test()
    {
        return "This is the test page";
    }
}

Markup berikut mengirimkan formulir ke /Home/Test titik akhir.

<form method="post">
    <button asp-route="Custom">Click Me</button>
    <input type="image" src="..." alt="Or Click Me" asp-route="Custom">
</form>

Markup sebelumnya menghasilkan HTML berikut:

<form method="post">
    <button formaction="/Home/Test">Click Me</button>
    <input type="image" src="..." alt="Or Click Me" formaction="/Home/Test">
</form>

Pembantu Tag Input

Pembantu Tag Input mengikat elemen input> HTML <ke ekspresi model dalam tampilan pisau cukur Anda.

Sintaks:

<input asp-for="<Expression Name>">

Bantuan Tag Input:

  • id Menghasilkan atribut HTML dan name untuk nama ekspresi yang ditentukan dalam asp-for atribut . asp-for="Property1.Property2" setara dengan m => m.Property1.Property2. Nama ekspresi adalah apa yang digunakan untuk asp-for nilai atribut. Lihat bagian Nama ekspresi untuk informasi tambahan.

  • Mengatur nilai atribut HTML type berdasarkan jenis model dan atribut anotasi data yang diterapkan ke properti model

  • Tidak akan menimpa nilai atribut HTML type saat nilai ditentukan

  • Menghasilkan atribut validasi HTML5 dari atribut anotasi data yang diterapkan ke properti model

  • Memiliki fitur Pembantu HTML yang tumpang tindih dengan Html.TextBoxFor dan Html.EditorFor. Lihat bagian Alternatif Pembantu HTML untuk Input Tag Helper untuk detailnya.

  • Memberikan pengetikan yang kuat. Jika nama properti berubah dan Anda tidak memperbarui Pembantu Tag, Anda akan mendapatkan kesalahan yang mirip dengan yang berikut ini:

    An error occurred during the compilation of a resource required to process
    this request. Please review the following specific error details and modify
    your source code appropriately.
    
    Type expected
    'RegisterViewModel' does not contain a definition for 'Email' and no
    extension method 'Email' accepting a first argument of type 'RegisterViewModel'
    could be found (are you missing a using directive or an assembly reference?)
    

Pembantu Input Tag mengatur atribut HTML type berdasarkan jenis .NET. Tabel berikut mencantumkan beberapa jenis .NET umum dan jenis HTML yang dihasilkan (tidak setiap jenis .NET tercantum).

Jenis .NET Jenis input
Bool type="checkbox"
String type="text"
WaktuTanggal type="datetime-local"
Byte type="number"
Int type="number"
Single, Double type="number"

Tabel berikut menunjukkan beberapa atribut anotasi data umum yang akan dipetakan oleh pembantu tag input ke jenis input tertentu (tidak setiap atribut validasi tercantum):

Atribut Jenis input
[EmailAddress] type="email"
[Url] type="url"
[HiddenInput] type="hidden"
[Telepon] type="tel"
[DataType(DataType.Password)] type="password"
[DataType(DataType.Date)] type="date"
[DataType(DataType.Time)] type="time"

Sampel:

using System.ComponentModel.DataAnnotations;

namespace FormsTagHelper.ViewModels
{
    public class RegisterViewModel
    {
        [Required]
        [EmailAddress]
        [Display(Name = "Email Address")]
        public string Email { get; set; }

        [Required]
        [DataType(DataType.Password)]
        public string Password { get; set; }
    }
}
@model RegisterViewModel

<form asp-controller="Demo" asp-action="RegisterInput" method="post">
    Email:  <input asp-for="Email" /> <br />
    Password: <input asp-for="Password" /><br />
    <button type="submit">Register</button>
</form>

Kode di atas menghasilkan HTML berikut:

<form method="post" action="/Demo/RegisterInput">
    Email:
    <input type="email" data-val="true"
            data-val-email="The Email Address field is not a valid email address."
            data-val-required="The Email Address field is required."
            id="Email" name="Email" value=""><br>
    Password:
    <input type="password" data-val="true"
            data-val-required="The Password field is required."
            id="Password" name="Password"><br>
    <button type="submit">Register</button>
    <input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>

Anotasi data yang diterapkan ke Email properti dan Password menghasilkan metadata pada model. Pembantu Tag Input menggunakan metadata model dan menghasilkan atribut HTML5data-val-* (lihat Validasi Model). Atribut ini menjelaskan validator untuk dilampirkan ke bidang input. Ini menyediakan validasi HTML5 dan jQuery yang tidak mengganggu. Atribut yang tidak mengganggu memiliki format data-val-rule="Error Message", di mana aturan adalah nama aturan validasi (seperti data-val-required, , data-val-emaildata-val-maxlength, dll.) Jika pesan kesalahan disediakan dalam atribut , pesan akan ditampilkan sebagai nilai untuk data-val-rule atribut . Ada juga atribut formulir data-val-ruleName-argumentName="argumentValue" yang memberikan detail tambahan tentang aturan, misalnya, data-val-maxlength-max="1024" .

Saat mengikat beberapa input kontrol ke properti yang sama, kontrol yang dihasilkan berbagi yang sama id, yang membuat mark-up yang dihasilkan tidak valid. Untuk mencegah duplikat, tentukan id atribut untuk setiap kontrol secara eksplisit.

Kotak centang penyajian input tersembunyi

Kotak centang di HTML5 tidak mengirimkan nilai saat tidak dicentang. Untuk mengaktifkan nilai default yang akan dikirim untuk kotak centang yang tidak dicentang, Pembantu Tag Input menghasilkan input tersembunyi tambahan untuk kotak centang.

Misalnya, pertimbangkan markup berikut Razor yang menggunakan Input Tag Helper untuk properti IsCheckedmodel boolean :

<form method="post">
    <input asp-for="@Model.IsChecked" />
    <button type="submit">Submit</button>
</form>

Markup sebelumnya Razor menghasilkan markup HTML yang mirip dengan yang berikut ini:

<form method="post">
    <input name="IsChecked" type="checkbox" value="true" />
    <button type="submit">Submit</button>

    <input name="IsChecked" type="hidden" value="false" /> 
</form>

Markup HTML sebelumnya menunjukkan input tersembunyi tambahan dengan nama IsChecked dan nilai false. Secara default, input tersembunyi ini dirender di akhir formulir. Ketika formulir dikirimkan:

  • IsChecked Jika input kotak centang dicentang, keduanya true dan false dikirimkan sebagai nilai.
  • IsChecked Jika input kotak centang tidak dicentang, hanya nilai false input tersembunyi yang dikirimkan.

Proses pengikatan model ASP.NET Core hanya membaca nilai pertama saat mengikat bool nilai, yang menghasilkan kotak centang yang dicentang true dan false untuk kotak centang yang tidak dicentang.

Untuk mengonfigurasi perilaku penyajian input tersembunyi, atur CheckBoxHiddenInputRenderMode properti pada MvcViewOptions.HtmlHelperOptions. Contohnya:

services.Configure<MvcViewOptions>(options =>
    options.HtmlHelperOptions.CheckBoxHiddenInputRenderMode =
        CheckBoxHiddenInputRenderMode.None);

Kode sebelumnya menonaktifkan penyajian input tersembunyi untuk kotak centang dengan mengatur CheckBoxHiddenInputRenderMode ke CheckBoxHiddenInputRenderMode.None. Untuk semua mode penyajian yang tersedia, lihat CheckBoxHiddenInputRenderMode enum.

Alternatif Pembantu HTML untuk Pembantu Tag Input

Html.TextBox, Html.TextBoxFor, Html.Editor dan Html.EditorFor memiliki fitur yang tumpang tindih dengan Pembantu Tag Input. Pembantu Tag Input akan secara otomatis mengatur type atribut; Html.TextBox dan Html.TextBoxFor tidak akan. Html.Editor dan Html.EditorFor menangani koleksi, objek dan templat kompleks; Pembantu Tag Input tidak. Pembantu Tag Input, Html.EditorFor dan Html.TextBoxFor sangat ditik (mereka menggunakan ekspresi lambda); Html.TextBox dan Html.Editor bukan (mereka menggunakan nama ekspresi).

HtmlAttributes

@Html.Editor() dan @Html.EditorFor() gunakan entri khusus ViewDataDictionary bernama htmlAttributes saat menjalankan templat default mereka. Perilaku ini secara opsional ditambungkan menggunakan additionalViewData parameter. Kunci "htmlAttributes" tidak peka huruf besar/kecil. Kunci "htmlAttributes" ditangani mirip dengan objek yang htmlAttributes diteruskan ke pembantu input seperti @Html.TextBox().

@Html.EditorFor(model => model.YourProperty, 
  new { htmlAttributes = new { @class="myCssClass", style="Width:100px" } })

Nama ekspresi

Nilai asp-for atribut adalah ModelExpression dan sisi kanan ekspresi lambda. Oleh karena itu, asp-for="Property1" menjadi m => m.Property1 dalam kode yang dihasilkan, itulah sebabnya Anda tidak perlu mengawali dengan Model. Anda dapat menggunakan karakter "@" untuk memulai ekspresi sebaris dan berpindah sebelum m.:

@{
  var joe = "Joe";
}

<input asp-for="@joe">

Menghasilkan hal berikut:

<input type="text" id="joe" name="joe" value="Joe">

Dengan properti koleksi, asp-for="CollectionProperty[23].Member" menghasilkan nama yang sama seperti asp-for="CollectionProperty[i].Member" ketika i memiliki nilai 23.

Ketika ASP.NET Core MVC menghitung nilai ModelExpression, ia memeriksa beberapa sumber, termasuk ModelState. Pertimbangkan <input type="text" asp-for="Name">. Atribut terhitung value adalah nilai non-null pertama dari:

  • ModelState entri dengan kunci "Nama".
  • Hasil ekspresi Model.Name.

Anda juga dapat menavigasi ke properti turunan menggunakan jalur properti model tampilan. Pertimbangkan kelas model yang lebih kompleks yang berisi properti anak Address .

public class AddressViewModel
{
    public string AddressLine1 { get; set; }
}
public class RegisterAddressViewModel
{
    public string Email { get; set; }

    [DataType(DataType.Password)]
    public string Password { get; set; }

    public AddressViewModel Address { get; set; }
}

Dalam tampilan, kami mengikat ke Address.AddressLine1:

@model RegisterAddressViewModel

<form asp-controller="Demo" asp-action="RegisterAddress" method="post">
    Email:  <input asp-for="Email" /> <br />
    Password: <input asp-for="Password" /><br />
    Address: <input asp-for="Address.AddressLine1" /><br />
    <button type="submit">Register</button>
</form>

HTML berikut dibuat untuk Address.AddressLine1:

<input type="text" id="Address_AddressLine1" name="Address.AddressLine1" value="">

Nama ekspresi dan Koleksi

Sampel, model yang berisi array dari Colors:

public class Person
{
    public List<string> Colors { get; set; }

    public int Age { get; set; }
}

Metode tindakan:

public IActionResult Edit(int id, int colorIndex)
{
    ViewData["Index"] = colorIndex;
    return View(GetPerson(id));
}

Berikut ini Razor memperlihatkan cara Anda mengakses elemen tertentu Color :

@model Person
@{
    var index = (int)ViewData["index"];
}

<form asp-controller="ToDo" asp-action="Edit" method="post">
    @Html.EditorFor(m => m.Colors[index])
    <label asp-for="Age"></label>
    <input asp-for="Age" /><br />
    <button type="submit">Post</button>
</form>

Templat Views/Shared/EditorTemplates/String.cshtml :

@model string

<label asp-for="@Model"></label>
<input asp-for="@Model" /> <br />

Sampel menggunakan List<T>:

public class ToDoItem
{
    public string Name { get; set; }

    public bool IsDone { get; set; }
}

Berikut ini Razor memperlihatkan cara melakukan iterasi atas koleksi:

@model List<ToDoItem>

<form asp-controller="ToDo" asp-action="Edit" method="post">
    <table>
        <tr> <th>Name</th> <th>Is Done</th> </tr>

        @for (int i = 0; i < Model.Count; i++)
        {
            <tr>
                @Html.EditorFor(model => model[i])
            </tr>
        }

    </table>
    <button type="submit">Save</button>
</form>

Templat Views/Shared/EditorTemplates/ToDoItem.cshtml :

@model ToDoItem

<td>
    <label asp-for="@Model.Name"></label>
    @Html.DisplayFor(model => model.Name)
</td>
<td>
    <input asp-for="@Model.IsDone" />
</td>

@*
    This template replaces the following Razor which evaluates the indexer three times.
    <td>
         <label asp-for="@Model[i].Name"></label>
         @Html.DisplayFor(model => model[i].Name)
     </td>
     <td>
         <input asp-for="@Model[i].IsDone" />
     </td>
*@

foreach harus digunakan jika memungkinkan ketika nilai akan digunakan dalam konteks atau asp-forHtml.DisplayFor setara. Secara umum, for lebih baik daripada foreach (jika skenario memungkinkannya) karena tidak perlu mengalokasikan enumerator; namun, mengevaluasi pengindeks dalam ekspresi LINQ bisa mahal dan harus diminimalkan.

 

Catatan

Kode sampel yang dikomentari di atas menunjukkan bagaimana Anda akan mengganti ekspresi lambda dengan @ operator untuk mengakses masing-masing ToDoItem dalam daftar.

Pembantu Tag Textarea

Pembantu Textarea Tag Helper tag mirip dengan Pembantu Tag Input.

  • id Menghasilkan atribut dan name , dan atribut validasi data dari model untuk <elemen textarea>.

  • Memberikan pengetikan yang kuat.

  • Alternatif Pembantu HTML: Html.TextAreaFor

Sampel:

using System.ComponentModel.DataAnnotations;

namespace FormsTagHelper.ViewModels
{
    public class DescriptionViewModel
    {
        [MinLength(5)]
        [MaxLength(1024)]
        public string Description { get; set; }
    }
}
@model DescriptionViewModel

<form asp-controller="Demo" asp-action="RegisterTextArea" method="post">
    <textarea asp-for="Description"></textarea>
    <button type="submit">Test</button>
</form>

HTML berikut dihasilkan:

<form method="post" action="/Demo/RegisterTextArea">
  <textarea data-val="true"
   data-val-maxlength="The field Description must be a string or array type with a maximum length of &#x27;1024&#x27;."
   data-val-maxlength-max="1024"
   data-val-minlength="The field Description must be a string or array type with a minimum length of &#x27;5&#x27;."
   data-val-minlength-min="5"
   id="Description" name="Description">
  </textarea>
  <button type="submit">Test</button>
  <input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>

Pembantu Tag Label

  • Menghasilkan keterangan label dan for atribut pada <elemen label> untuk nama ekspresi

  • Alternatif Pembantu HTML: Html.LabelFor.

Label Tag Helper memberikan manfaat berikut atas elemen label HTML murni:

  • Anda secara otomatis mendapatkan nilai label deskriptif dari Display atribut . Nama tampilan yang dimaksudkan mungkin berubah dari waktu ke waktu, dan kombinasi Display atribut dan Label Tag Helper akan menerapkan di Display mana pun nama tersebut digunakan.

  • Lebih sedikit markup dalam kode sumber

  • Pengetikan yang kuat dengan properti model.

Sampel:

using System.ComponentModel.DataAnnotations;

namespace FormsTagHelper.ViewModels
{
    public class SimpleViewModel
    {
        [Required]
        [EmailAddress]
        [Display(Name = "Email Address")]
        public string Email { get; set; }
    }
}

@model SimpleViewModel

<form asp-controller="Demo" asp-action="RegisterLabel" method="post">
    <label asp-for="Email"></label>
    <input asp-for="Email" /> <br />
</form>

HTML berikut dihasilkan untuk <label> elemen :

<label for="Email">Email Address</label>

Label Tag Helper menghasilkan for nilai atribut "Email", yang merupakan ID yang terkait dengan <input> elemen . Pembantu Tag menghasilkan elemen dan for konsisten id sehingga dapat dikaitkan dengan benar. Keterangan dalam sampel ini berasal dari Display atribut . Jika model tidak berisi Display atribut, keterangannya akan menjadi nama properti ekspresi. Untuk mengambil alih keterangan default, tambahkan keterangan di dalam tag label.

Pembantu Tag Validasi

Ada dua Pembantu Tag Validasi. Validation Message Tag Helper (yang menampilkan pesan validasi untuk satu properti pada model Anda), dan Validation Summary Tag Helper (yang menampilkan ringkasan kesalahan validasi). Menambahkan Input Tag Helper atribut validasi sisi klien HTML5 ke elemen input berdasarkan atribut anotasi data pada kelas model Anda. Validasi juga dilakukan pada server. Pembantu Tag Validasi menampilkan pesan kesalahan ini ketika terjadi kesalahan validasi.

Pembantu Tag Pesan Validasi

  • Menambahkan atribut HTML5data-valmsg-for="property" ke elemen rentang, yang melampirkan pesan kesalahan validasi pada bidang input properti model yang ditentukan. Ketika kesalahan validasi sisi klien terjadi, jQuery menampilkan pesan kesalahan dalam <span> elemen .

  • Validasi juga terjadi di server. Klien mungkin menonaktifkan JavaScript dan beberapa validasi hanya dapat dilakukan di sisi server.

  • Alternatif Pembantu HTML: Html.ValidationMessageFor

Validation Message Tag Helper digunakan dengan asp-validation-for atribut pada elemen rentang HTML.

<span asp-validation-for="Email"></span>

Pembantu Tag Pesan Validasi akan menghasilkan HTML berikut:

<span class="field-validation-valid"
  data-valmsg-for="Email"
  data-valmsg-replace="true"></span>

Anda umumnya menggunakan setelah Pembantu Validation Message Tag HelperInput Tag untuk properti yang sama. Melakukannya menampilkan pesan kesalahan validasi di dekat input yang menyebabkan kesalahan.

Catatan

Anda harus memiliki tampilan dengan referensi skrip JavaScript dan jQuery yang benar untuk validasi sisi klien. Lihat Validasi Model untuk informasi selengkapnya.

Ketika kesalahan validasi sisi server terjadi (misalnya ketika Anda memiliki validasi sisi server kustom atau validasi sisi klien dinonaktifkan), MVC menempatkan pesan kesalahan tersebut sebagai isi <span> elemen.

<span class="field-validation-error" data-valmsg-for="Email"
            data-valmsg-replace="true">
   The Email Address field is required.
</span>

Pembantu Tag Ringkasan Validasi

  • Menargetkan <div> elemen dengan asp-validation-summary atribut

  • Alternatif Pembantu HTML: @Html.ValidationSummary

Validation Summary Tag Helper digunakan untuk menampilkan ringkasan pesan validasi. Nilai asp-validation-summary atribut dapat berupa salah satu hal berikut:

asp-validation-summary Pesan validasi ditampilkan
All Tingkat properti dan model
ModelOnly Model
None Tidak ada

Sampel

Dalam contoh berikut, model data memiliki DataAnnotation atribut, yang menghasilkan pesan kesalahan validasi pada <input> elemen . Ketika terjadi kesalahan validasi, Pembantu Tag Validasi menampilkan pesan kesalahan:

using System.ComponentModel.DataAnnotations;

namespace FormsTagHelper.ViewModels
{
    public class RegisterViewModel
    {
        [Required]
        [EmailAddress]
        [Display(Name = "Email Address")]
        public string Email { get; set; }

        [Required]
        [DataType(DataType.Password)]
        public string Password { get; set; }
    }
}
@model RegisterViewModel

<form asp-controller="Demo" asp-action="RegisterValidation" method="post">
    <div asp-validation-summary="ModelOnly"></div>
    Email:  <input asp-for="Email" /> <br />
    <span asp-validation-for="Email"></span><br />
    Password: <input asp-for="Password" /><br />
    <span asp-validation-for="Password"></span><br />
    <button type="submit">Register</button>
</form>

HTML yang dihasilkan (ketika model valid):

<form action="/DemoReg/Register" method="post">
  Email:  <input name="Email" id="Email" type="email" value=""
   data-val-required="The Email field is required."
   data-val-email="The Email field is not a valid email address."
   data-val="true"><br>
  <span class="field-validation-valid" data-valmsg-replace="true"
   data-valmsg-for="Email"></span><br>
  Password: <input name="Password" id="Password" type="password"
   data-val-required="The Password field is required." data-val="true"><br>
  <span class="field-validation-valid" data-valmsg-replace="true"
   data-valmsg-for="Password"></span><br>
  <button type="submit">Register</button>
  <input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>

Pilih Pembantu Tag

menentukan nama properti model untuk elemen pilih dan asp-items menentukan elemen opsi.Select Tag Helperasp-for Contohnya:

<select asp-for="Country" asp-items="Model.Countries"></select> 

Sampel:

using Microsoft.AspNetCore.Mvc.Rendering;
using System.Collections.Generic;

namespace FormsTagHelper.ViewModels
{
    public class CountryViewModel
    {
        public string Country { get; set; }

        public List<SelectListItem> Countries { get; } = new List<SelectListItem>
        {
            new SelectListItem { Value = "MX", Text = "Mexico" },
            new SelectListItem { Value = "CA", Text = "Canada" },
            new SelectListItem { Value = "US", Text = "USA"  },
        };
    }
}

Metode Index ini menginisialisasi CountryViewModel, mengatur negara yang dipilih dan meneruskannya ke Index tampilan.

public IActionResult Index()
{
    var model = new CountryViewModel();
    model.Country = "CA";
    return View(model);
}

Metode HTTP POST Index menampilkan pilihan:

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Index(CountryViewModel model)
{
    if (ModelState.IsValid)
    {
        var msg = model.Country + " selected";
        return RedirectToAction("IndexSuccess", new { message = msg });
    }

    // If we got this far, something failed; redisplay form.
    return View(model);
}

Tampilan Index :

@model CountryViewModel

<form asp-controller="Home" asp-action="Index" method="post">
    <select asp-for="Country" asp-items="Model.Countries"></select> 
    <br /><button type="submit">Register</button>
</form>

Yang menghasilkan HTML berikut (dengan "CA" dipilih):

<form method="post" action="/">
     <select id="Country" name="Country">
       <option value="MX">Mexico</option>
       <option selected="selected" value="CA">Canada</option>
       <option value="US">USA</option>
     </select>
       <br /><button type="submit">Register</button>
     <input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
   </form>

Catatan

Kami tidak merekomendasikan penggunaan ViewBag atau ViewData dengan Pilih Pembantu Tag. Model tampilan lebih kuat dalam menyediakan metadata MVC dan umumnya kurang bermasalah.

Nilai asp-for atribut adalah kasus khusus dan tidak memerlukan Model awalan, atribut Pembantu Tag lainnya melakukan (seperti asp-items)

<select asp-for="Country" asp-items="Model.Countries"></select> 

Pengikatan enum

Seringkali lebih mudah digunakan <select> dengan enum properti dan menghasilkan SelectListItem elemen dari enum nilai.

Sampel:

public class CountryEnumViewModel
{
    public CountryEnum EnumCountry { get; set; }
}
using System.ComponentModel.DataAnnotations;

namespace FormsTagHelper.ViewModels
{
    public enum CountryEnum
    {
        [Display(Name = "United Mexican States")]
        Mexico,
        [Display(Name = "United States of America")]
        USA,
        Canada,
        France,
        Germany,
        Spain
    }
}

Metode ini GetEnumSelectList menghasilkan SelectList objek untuk enum.

@model CountryEnumViewModel

<form asp-controller="Home" asp-action="IndexEnum" method="post">
    <select asp-for="EnumCountry" 
            asp-items="Html.GetEnumSelectList<CountryEnum>()">
    </select> 
    <br /><button type="submit">Register</button>
</form>

Anda dapat menandai daftar enumerator Anda dengan Display atribut untuk mendapatkan UI yang lebih kaya:

using System.ComponentModel.DataAnnotations;

namespace FormsTagHelper.ViewModels
{
    public enum CountryEnum
    {
        [Display(Name = "United Mexican States")]
        Mexico,
        [Display(Name = "United States of America")]
        USA,
        Canada,
        France,
        Germany,
        Spain
    }
}

HTML berikut dihasilkan:

<form method="post" action="/Home/IndexEnum">
    <select data-val="true" data-val-required="The EnumCountry field is required."
            id="EnumCountry" name="EnumCountry">
        <option value="0">United Mexican States</option>
        <option value="1">United States of America</option>
        <option value="2">Canada</option>
        <option value="3">France</option>
        <option value="4">Germany</option>
        <option selected="selected" value="5">Spain</option>
    </select>
    <br /><button type="submit">Register</button>
    <input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>

Grup Opsi

Elemen optgroup> HTML <dihasilkan saat model tampilan berisi satu atau beberapa SelectListGroup objek.

Kelompokkan CountryViewModelGroupSelectListItem elemen ke dalam grup "Amerika Utara" dan "Eropa":

public class CountryViewModelGroup
{
    public CountryViewModelGroup()
    {
        var NorthAmericaGroup = new SelectListGroup { Name = "North America" };
        var EuropeGroup = new SelectListGroup { Name = "Europe" };

        Countries = new List<SelectListItem>
        {
            new SelectListItem
            {
                Value = "MEX",
                Text = "Mexico",
                Group = NorthAmericaGroup
            },
            new SelectListItem
            {
                Value = "CAN",
                Text = "Canada",
                Group = NorthAmericaGroup
            },
            new SelectListItem
            {
                Value = "US",
                Text = "USA",
                Group = NorthAmericaGroup
            },
            new SelectListItem
            {
                Value = "FR",
                Text = "France",
                Group = EuropeGroup
            },
            new SelectListItem
            {
                Value = "ES",
                Text = "Spain",
                Group = EuropeGroup
            },
            new SelectListItem
            {
                Value = "DE",
                Text = "Germany",
                Group = EuropeGroup
            }
      };
    }

    public string Country { get; set; }

    public List<SelectListItem> Countries { get; }

Dua grup ditunjukkan di bawah ini:

option group example

HTML yang dihasilkan:

 <form method="post" action="/Home/IndexGroup">
      <select id="Country" name="Country">
          <optgroup label="North America">
              <option value="MEX">Mexico</option>
              <option value="CAN">Canada</option>
              <option value="US">USA</option>
          </optgroup>
          <optgroup label="Europe">
              <option value="FR">France</option>
              <option value="ES">Spain</option>
              <option value="DE">Germany</option>
          </optgroup>
      </select>
      <br /><button type="submit">Register</button>
      <input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
 </form>

Pilih beberapa

Pilih Pembantu Tag akan secara otomatis menghasilkan atribut multiple = "multiple" jika properti yang ditentukan dalam asp-for atribut adalah IEnumerable. Misalnya, mengingat model berikut:

using Microsoft.AspNetCore.Mvc.Rendering;
using System.Collections.Generic;

namespace FormsTagHelper.ViewModels
{
    public class CountryViewModelIEnumerable
    {
        public IEnumerable<string> CountryCodes { get; set; }

        public List<SelectListItem> Countries { get; } = new List<SelectListItem>
        {
            new SelectListItem { Value = "MX", Text = "Mexico" },
            new SelectListItem { Value = "CA", Text = "Canada" },
            new SelectListItem { Value = "US", Text = "USA"    },
            new SelectListItem { Value = "FR", Text = "France" },
            new SelectListItem { Value = "ES", Text = "Spain"  },
            new SelectListItem { Value = "DE", Text = "Germany"}
         };
    }
}

Dengan tampilan berikut:

@model CountryViewModelIEnumerable

<form asp-controller="Home" asp-action="IndexMultiSelect" method="post">
    <select asp-for="CountryCodes" asp-items="Model.Countries"></select> 
    <br /><button type="submit">Register</button>
</form>

Menghasilkan HTML berikut:

<form method="post" action="/Home/IndexMultiSelect">
    <select id="CountryCodes"
    multiple="multiple"
    name="CountryCodes"><option value="MX">Mexico</option>
<option value="CA">Canada</option>
<option value="US">USA</option>
<option value="FR">France</option>
<option value="ES">Spain</option>
<option value="DE">Germany</option>
</select>
    <br /><button type="submit">Register</button>
  <input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>

Tidak ada pilihan

Jika Anda menemukan diri Anda menggunakan opsi "tidak ditentukan" di beberapa halaman, Anda dapat membuat templat untuk menghilangkan pengulangan HTML:

@model CountryViewModel

<form asp-controller="Home" asp-action="IndexEmpty" method="post">
    @Html.EditorForModel()
    <br /><button type="submit">Register</button>
</form>

Templat Views/Shared/EditorTemplates/CountryViewModel.cshtml :

@model CountryViewModel

<select asp-for="Country" asp-items="Model.Countries">
    <option value="">--none--</option>
</select>

Menambahkan elemen opsi> HTML <tidak terbatas pada kasus Tidak ada pilihan. Misalnya, metode tampilan dan tindakan berikut akan menghasilkan HTML yang mirip dengan kode di atas:

public IActionResult IndexNone()
{
    var model = new CountryViewModel();
    model.Countries.Insert(0, new SelectListItem("<none>", ""));
    return View(model);
}
@model CountryViewModel

<form asp-controller="Home" asp-action="IndexEmpty" method="post">
    <select asp-for="Country">
        <option value="">&lt;none&gt;</option>
        <option value="MX">Mexico</option>
        <option value="CA">Canada</option>
        <option value="US">USA</option>
    </select> 
    <br /><button type="submit">Register</button>
</form>

Elemen yang benar <option> akan dipilih ( berisi selected="selected" atribut) tergantung pada nilai saat ini Country .

public IActionResult IndexOption(int id)
{
    var model = new CountryViewModel();
    model.Country = "CA";
    return View(model);
}
 <form method="post" action="/Home/IndexEmpty">
      <select id="Country" name="Country">
          <option value="">&lt;none&gt;</option>
          <option value="MX">Mexico</option>
          <option value="CA" selected="selected">Canada</option>
          <option value="US">USA</option>
      </select>
      <br /><button type="submit">Register</button>
   <input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
 </form>

Sumber Daya Tambahan: