Nguon: Microsoft Learn · .NET 8.0

Select Tag Helper trong ASP.NET Core

Nguồn: Tag Helpers in forms - The Select Tag Helper

Select Tag Helper

Select Tag Helper (Tag Helper Select):

Thuộc tính asp-for của Select Tag Helper chỉ định tên property của model cho phần tử selectasp-items chỉ định các phần tử option. Ví dụ:

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

Ví dụ:

csharp
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" },
        };
    }
}

Phương thức Index khởi tạo CountryViewModel, thiết lập quốc gia được chọn và truyền nó đến view (khung nhìn) Index.

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

Phương thức Index HTTP POST hiển thị lựa chọn:

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

View Index:

cshtml
@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>

Tạo ra HTML sau (với "CA" được chọn):

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

Lưu ý: Không nên sử dụng ViewBag hoặc ViewData với Select Tag Helper. View model (mô hình view) cung cấp metadata (siêu dữ liệu) MVC mạnh mẽ hơn và ít gặp vấn đề hơn.

Giá trị thuộc tính asp-for là trường hợp đặc biệt và không cần tiền tố Model. Các thuộc tính Tag Helper khác thì có (chẳng hạn như asp-items).

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

Liên kết Enum

Thường thuận tiện khi sử dụng <select> với property kiểu enum (kiểu liệt kê) và tạo các phần tử SelectListItem từ các giá trị enum.

Ví dụ:

csharp
public class CountryEnumViewModel
{
    public CountryEnum EnumCountry { get; set; }
}
csharp
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
    }
}

Phương thức GetEnumSelectList tạo đối tượng SelectList cho một enum.

cshtml
@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>

Bạn có thể đánh dấu danh sách enumerator (bộ liệt kê) với thuộc tính Display để có giao diện phong phú hơn:

csharp
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 được tạo ra:

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

Nhóm tùy chọn (Option Group)

Phần tử HTML &lt;optgroup&gt; được tạo ra khi view model chứa một hoặc nhiều đối tượng SelectListGroup.

CountryViewModelGroup nhóm các phần tử SelectListItem vào các nhóm "North America" (Bắc Mỹ) và "Europe" (Châu Âu):

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

HTML được tạo ra:

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

Chọn nhiều (Multiple select)

Select Tag Helper sẽ tự động tạo thuộc tính multiple = "multiple" nếu property được chỉ định trong thuộc tính asp-forIEnumerable. Ví dụ, với model sau:

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

Với view sau:

cshtml
@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>

Tạo ra HTML sau:

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

Không có lựa chọn nào (No selection)

Nếu bạn thấy mình sử dụng tùy chọn "không chỉ định" trên nhiều trang, bạn có thể tạo một template (mẫu) để tránh lặp lại HTML:

cshtml
@model CountryViewModel

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

Template Views/Shared/EditorTemplates/CountryViewModel.cshtml:

cshtml
@model CountryViewModel

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

Việc thêm các phần tử HTML &lt;option&gt; không bị giới hạn trong trường hợp Không có lựa chọn. Ví dụ, view và action method (phương thức hành động) sau sẽ tạo HTML tương tự như code trước:

csharp
public IActionResult IndexNone()
{
    var model = new CountryViewModel();
    model.Countries.Insert(0, new SelectListItem("<none>", ""));
    return View(model);
}
cshtml
@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>

Phần tử <option> đúng sẽ được chọn (chứa thuộc tính selected="selected") tùy thuộc vào giá trị Country hiện tại.

csharp
public IActionResult IndexOption(int id)
{
    var model = new CountryViewModel();
    model.Country = "CA";
    return View(model);
}
html
 <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>