ASP.NET Core 表單中的標籤協助程式Tag Helpers in forms in ASP.NET Core

作者:Rick AndersonN. Taylor MullenDave PaquetteJerrie PelserBy Rick Anderson, N. Taylor Mullen, Dave Paquette, and Jerrie Pelser

本文件示範使用表單和常用在表單上的 HTML 項目。This document demonstrates working with Forms and the HTML elements commonly used on a Form. HTML 表單項目提供用來將資料張貼回伺服器的主要機制 Web 應用程式。The HTML Form element provides the primary mechanism web apps use to post back data to the server. 本文件的大部分在描述標籤協助程式,以及它們如何協助您有效率地建立強大的 HTML 表單。Most of this document describes Tag Helpers and how they can help you productively create robust HTML forms. 我們建議您先閱讀標籤協助程式簡介,然後才閱讀這份文件。We recommend you read Introduction to Tag Helpers before you read this document.

在許多情況下,HTML 協助程式都會提供特定標籤協助程式的替代方式,但請務必辨識標籤協助程式未取代 HTML 協助程式,而且每個 HTML 協助程式都沒有標籤協助程式。In many cases, HTML Helpers provide an alternative approach to a specific Tag Helper, but it's important to recognize that Tag Helpers don't replace HTML Helpers and there's not a Tag Helper for each HTML Helper. 有 HTML 協助程式替代存在時,便會予以提及。When an HTML Helper alternative exists, it's mentioned.

表單標籤協助程式The Form Tag Helper

表單標籤協助程式:The Form Tag Helper:

  • 產生 MVC 控制器動作或具名路由的 HTML <FORM> action 屬性值Generates the HTML <FORM> action attribute value for a MVC controller action or named route

  • 產生隱藏的要求驗證權杖,以防止跨站台要求偽造 (搭配 HTTP Post 動作方法中的 [ValidateAntiForgeryToken] 屬性使用時)Generates a hidden Request Verification Token to prevent cross-site request forgery (when used with the [ValidateAntiForgeryToken] attribute in the HTTP Post action method)

  • 提供 asp-route-<Parameter Name> 屬性,其中 <Parameter Name> 新增至路由值。Provides the asp-route-<Parameter Name> attribute, where <Parameter Name> is added to the route values. Html.BeginFormHtml.BeginRouteFormrouteValues 參數提供類似的功能。The routeValues parameters to Html.BeginForm and Html.BeginRouteForm provide similar functionality.

  • 有 HTML 協助程式的替代 Html.BeginFormHtml.BeginRouteFormHas an HTML Helper alternative Html.BeginForm and Html.BeginRouteForm

範例:Sample:

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

上述表單標籤協助程式會產生下列 HTML:The Form Tag Helper above generates the following HTML:

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

MVC 執行階段會從表單標籤協助程式屬性 asp-controllerasp-action 產生 action 屬性值。The MVC runtime generates the action attribute value from the Form Tag Helper attributes asp-controller and asp-action. 表單標籤協助程式也會產生隱藏的要求驗證權杖,以防止跨站台要求偽造 (搭配 HTTP Post 動作方法中的 [ValidateAntiForgeryToken] 屬性使用時)。The Form Tag Helper also generates a hidden Request Verification Token to prevent cross-site request forgery (when used with the [ValidateAntiForgeryToken] attribute in the HTTP Post action method). 保護純粹的 HTML 表單抵禦跨站台要求偽造很困難,而表單標籤協助程式為您提供此服務。Protecting a pure HTML Form from cross-site request forgery is difficult, the Form Tag Helper provides this service for you.

使用具名路由Using a named route

asp-route 標籤協助程式屬性也可以產生 HTML action 屬性的標記。The asp-route Tag Helper attribute can also generate markup for the HTML action attribute. 具有名為 register路由的應用程式,可能針對註冊頁面使用下列標記:An app with a route named register could use the following markup for the registration page:

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

Views/Account 資料夾 (當您建立具有「個別使用者帳戶」的新 Web 應用程式時產生) 中的許多檢視表,包含 asp-route-returnurl 屬性:Many of the views in the Views/Account folder (generated when you create a new web app with Individual User Accounts) contain the asp-route-returnurl attribute:

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

注意

使用內建的範本,returnUrl 只會在您嘗試存取授權的資源,但未經過驗證或授權時才自動填入。With the built in templates, returnUrl is only populated automatically when you try to access an authorized resource but are not authenticated or authorized. 當您嘗試未經授權的存取時,安全性中介軟體會將您重新導向到登入頁面,並設定 returnUrlWhen you attempt an unauthorized access, the security middleware redirects you to the login page with the returnUrl set.

表單動作標記協助程式The Form Action Tag Helper

表單動作標記協助程式會在產生的 <button ...><input type="image" ...> 標記上產生 formaction 屬性。The Form Action Tag Helper generates the formaction attribute on the generated <button ...> or <input type="image" ...> tag. formaction 屬性可讓您控制表單提交其資料的位置。The formaction attribute controls where a form submits its data. 它會繫結至類型 image<input> 元素和 <button> 元素。It binds to <input> elements of type image and <button> elements. 表單動作標記協助程式允許使用多個 AnchorTagHelper asp- 屬性來控制會為相應元素產生哪個 formaction 連結。The Form Action Tag Helper enables the usage of several AnchorTagHelper asp- attributes to control what formaction link is generated for the corresponding element.

支援 AnchorTagHelper 屬性來控制 formaction 的值:Supported AnchorTagHelper attributes to control the value of formaction:

屬性Attribute 描述Description
asp-controllerasp-controller 控制器的名稱。The name of the controller.
asp-actionasp-action 動作方法的名稱。The name of the action method.
asp-areaasp-area 區域的名稱。The name of the area.
asp-pageasp-page Razor 頁面的名稱。The name of the Razor page.
asp-page-handlerasp-page-handler Razor 頁面處理常式的名稱。The name of the Razor page handler.
asp-routeasp-route 路徑的名稱。The name of the route.
asp-route-{value}asp-route-{value} 單一 URL 路由值。A single URL route value. 例如,asp-route-id="1234"For example, asp-route-id="1234".
asp-all-route-dataasp-all-route-data 所有路由值。All route values.
asp-fragmentasp-fragment URL 片段。The URL fragment.

提交至控制器範例Submit to controller example

輸入或選取按鈕時,下列標記會將表單提交到 HomeControllerIndex 動作:The following markup submits the form to the Index action of HomeController when the input or button are selected:

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

上述標記會產生下列 HTML:The previous markup generates following HTML:

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

提交至頁面範例Submit to page example

下列標記會將表單提交到 About Razor 頁面:The following markup submits the form to the About Razor Page:

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

上述標記會產生下列 HTML:The previous markup generates following HTML:

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

提交至路由範例Submit to route example

請考量 /Home/Test 端點:Consider the /Home/Test endpoint:

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

下列標記會將表單提交到 /Home/Test 端點。The following markup submits the form to the /Home/Test endpoint.

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

上述標記會產生下列 HTML:The previous markup generates following HTML:

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

輸入標籤協助程式The Input Tag Helper

輸入標籤協助程式會將 HTML <input> 項目繫結到 Razor 檢視中的模型運算式。The Input Tag Helper binds an HTML <input> element to a model expression in your razor view.

語法:Syntax:

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

輸入標籤協助程式:The Input Tag Helper:

  • 會為 asp-for 屬性中指定的運算式名稱產生 idname HTML 屬性。Generates the id and name HTML attributes for the expression name specified in the asp-for attribute. asp-for="Property1.Property2" 相當於 m => m.Property1.Property2asp-for="Property1.Property2" is equivalent to m => m.Property1.Property2. 運算式的名稱用於 asp-for 屬性值。The name of the expression is what is used for the asp-for attribute value. 請參閱運算式名稱一節以取得其他資訊。See the Expression names section for additional information.

  • 根據套用至模型屬性的模型類型和資料註解屬性,設定 HTML type 屬性值Sets the HTML type attribute value based on the model type and data annotation attributes applied to the model property

  • 已指定 HTML type 屬性值時不會予以覆寫Won't overwrite the HTML type attribute value when one is specified

  • 從套用至模型屬性的資料註解屬性產生 HTML5 驗證屬性Generates HTML5 validation attributes from data annotation attributes applied to model properties

  • Html.TextBoxForHtml.EditorFor 具有 HTML 協助程式功能重疊。Has an HTML Helper feature overlap with Html.TextBoxFor and Html.EditorFor. 如需詳細資訊,請參閱輸入標籤協助程式的 HTML 協助程式替代See the HTML Helper alternatives to Input Tag Helper section for details.

  • 提供強型別。Provides strong typing. 如果屬性的名稱變更,而您未更新標籤協助程式,則會出現如下所示的錯誤:If the name of the property changes and you don't update the Tag Helper you'll get an error similar to the following:

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?)

Input 標籤協助程式會根據 .NET 型別設定 HTML type 屬性。The Input Tag Helper sets the HTML type attribute based on the .NET type. 下表列出一些常見的 .NET 型別和產生的 HTML 型別 (不是每個 .NET 類型都列出)。The following table lists some common .NET types and generated HTML type (not every .NET type is listed).

.NET 型別.NET type 輸入類型Input Type
BoolBool type="checkbox"type="checkbox"
StringString type="text"type="text"
DateTimeDateTime type="datetime-local"type="datetime-local"
ByteByte type="number"type="number"
IntInt type="number"type="number"
Single、DoubleSingle, Double type="number"type="number"

下表顯示輸入標籤協助程式將對應至特定的輸入類型的一些常見資料註解屬性 (不是每個驗證屬性都列出):The following table shows some common data annotations attributes that the input tag helper will map to specific input types (not every validation attribute is listed):

屬性Attribute 輸入類型Input Type
[EmailAddress][EmailAddress] type="email"type="email"
[Url][Url] type="url"type="url"
[HiddenInput][HiddenInput] type="hidden"type="hidden"
[Phone][Phone] type="tel"type="tel"
[DataType(DataType.Password)][DataType(DataType.Password)] type="password"type="password"
[DataType(DataType.Date)][DataType(DataType.Date)] type="date"type="date"
[DataType(DataType.Time)][DataType(DataType.Time)] type="time"type="time"

範例:Sample:

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>

上述程式碼會產生下列 HTML:The code above generates the following HTML:

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

套用至 EmailPassword 屬性的資料註解會產生模型的中繼資料。The data annotations applied to the Email and Password properties generate metadata on the model. 輸入標籤協助程式會取用模型中繼資料,並產生 HTML5 data-val-* 屬性 (請參閱模型驗證)。The Input Tag Helper consumes the model metadata and produces HTML5 data-val-* attributes (see Model Validation). 這些屬性描述要附加至輸入欄位的驗證程式。These attributes describe the validators to attach to the input fields. 這提供低調的 HTML5 和 jQuery 驗證。This provides unobtrusive HTML5 and jQuery validation. 不顯眼的屬性的格式為 data-val-rule="Error Message",其中 rule 是驗證規則的名稱(例如 data-val-requireddata-val-emaildata-val-maxlength等等)。如果在屬性中提供錯誤訊息,則會顯示為 data-val-rule 屬性的值。The unobtrusive attributes have the format data-val-rule="Error Message", where rule is the name of the validation rule (such as data-val-required, data-val-email, data-val-maxlength, etc.) If an error message is provided in the attribute, it's displayed as the value for the data-val-rule attribute. 另外還有 data-val-ruleName-argumentName="argumentValue" 格式的屬性,提供規則的其他詳細資料,例如 data-val-maxlength-max="1024"There are also attributes of the form data-val-ruleName-argumentName="argumentValue" that provide additional details about the rule, for example, data-val-maxlength-max="1024" .

輸入標籤協助程式的 HTML 標記替代HTML Helper alternatives to Input Tag Helper

Html.TextBoxHtml.TextBoxForHtml.EditorHtml.EditorFor 具有與輸入標籤協助程式重疊的功能。Html.TextBox, Html.TextBoxFor, Html.Editor and Html.EditorFor have overlapping features with the Input Tag Helper. 輸入標籤協助程式將會自動設定 type 屬性;而 Html.TextBoxHtml.TextBoxFor 不會。The Input Tag Helper will automatically set the type attribute; Html.TextBox and Html.TextBoxFor won't. Html.EditorHtml.EditorFor 會處理集合、複雜的物件和範本;而輸入標籤協助程式不會。Html.Editor and Html.EditorFor handle collections, complex objects and templates; the Input Tag Helper doesn't. 輸入標籤協助程式、Html.EditorForHtml.TextBoxFor 為強型別 (它們使用 Lambda 運算式);而 Html.TextBoxHtml.Editor 不是 (它們使用運算式名稱)。The Input Tag Helper, Html.EditorFor and Html.TextBoxFor are strongly typed (they use lambda expressions); Html.TextBox and Html.Editor are not (they use expression names).

HtmlAttributesHtmlAttributes

@Html.Editor()@Html.EditorFor() 執行它們的預設範本時,使用特殊的 ViewDataDictionary 項目,名為 htmlAttributes@Html.Editor() and @Html.EditorFor() use a special ViewDataDictionary entry named htmlAttributes when executing their default templates. 此行為會選擇性地使用 additionalViewData 參數來增強。This behavior is optionally augmented using additionalViewData parameters. 索引鍵 "htmlAttributes" 不區分大小寫。The key "htmlAttributes" is case-insensitive. 索引鍵 "htmlAttributes" 的處理方式類似於傳遞給輸入協助程式 (例如 @Html.TextBox())的 htmlAttributes 物件。The key "htmlAttributes" is handled similarly to the htmlAttributes object passed to input helpers like @Html.TextBox().

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

運算式名稱Expression names

asp-for 屬性值是 ModelExpression 和 Lambda 運算式的右邊。The asp-for attribute value is a ModelExpression and the right hand side of a lambda expression. 因此,asp-for="Property1" 在產生的程式碼中變成 m => m.Property1,這也是為什麼您不需要加上前置詞 Model 的原因。Therefore, asp-for="Property1" becomes m => m.Property1 in the generated code which is why you don't need to prefix with Model. 您可以使用 "@" 字元來起始內嵌運算式並將它移到 m. 前面:You can use the "@" character to start an inline expression and move before the m.:

@{
       var joe = "Joe";
   }
   <input asp-for="@joe">

產生下列內容:Generates the following:

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

搭配集合屬性,當 i 的值為 23 時,asp-for="CollectionProperty[23].Member" 會產生與 asp-for="CollectionProperty[i].Member" 相同的名稱。With collection properties, asp-for="CollectionProperty[23].Member" generates the same name as asp-for="CollectionProperty[i].Member" when i has the value 23.

當 ASP.NET Core MVC 計算 ModelExpression 的值時,會檢查幾個來源,其中包括ModelStateWhen ASP.NET Core MVC calculates the value of ModelExpression, it inspects several sources, including ModelState. 請考慮 <input type="text" asp-for="@Name">Consider <input type="text" asp-for="@Name">. 導出的 value 屬性是第一個非 null 的值,來自:The calculated value attribute is the first non-null value from:

  • 索引鍵為 "Name" 的 ModelState 項目。ModelState entry with key "Name".
  • 運算式 Model.Name 的結果。Result of the expression Model.Name.

您也可以使用檢視模型的屬性路徑巡覽至子屬性。You can also navigate to child properties using the property path of the view model. 請考慮更複雜的模型類別,其中包含子系 Address 屬性。Consider a more complex model class that contains a child Address property.

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

在檢視中,我們繫結至 Address.AddressLine1In the view, we bind to 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>

會為 Address.AddressLine1 產生下列 HTML:The following HTML is generated for Address.AddressLine1:

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

運算式名稱和集合Expression names and Collections

範例,包含 Colors 陣列的模型:Sample, a model containing an array of Colors:

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

    public int Age { get; set; }
}

動作方法:The action method:

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

下列 Razor 示範如何存取特定 Color 項目:The following Razor shows how you access a specific Color element:

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

Views/Shared/EditorTemplates/String.cshtml 範本:The Views/Shared/EditorTemplates/String.cshtml template:

@model string

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

使用 List<T> 的範例:Sample using List<T>:

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

    public bool IsDone { get; set; }
}

下列 Razor 示範如何逐一查看集合:The following Razor shows how to iterate over a collection:

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

Views/Shared/EditorTemplates/ToDoItem.cshtml 範本:The Views/Shared/EditorTemplates/ToDoItem.cshtml template:

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

當值將在 asp-forHtml.DisplayFor 相當內容中使用時,應該使用 foreach (如果可能的話)。foreach should be used if possible when the value is going to be used in an asp-for or Html.DisplayFor equivalent context. 一般而言,forforeach 好 (若案例允許的話),因為它不需要配置列舉程式;不過,評估 LINQ 運算式中的索引子可能成本高昂且應該儘可能避免。In general, for is better than foreach (if the scenario allows it) because it doesn't need to allocate an enumerator; however, evaluating an indexer in a LINQ expression can be expensive and should be minimized.

 

注意

上述加上註解的範例程式碼示範如何將 Lambda 運算式取代為 @ 運算子,來存取清單中的每個 ToDoItemThe commented sample code above shows how you would replace the lambda expression with the @ operator to access each ToDoItem in the list.

Textarea 標籤協助程式The Textarea Tag Helper

Textarea Tag Helper 標籤協助程式類似於輸入標籤協助程式。The Textarea Tag Helper tag helper is similar to the Input Tag Helper.

  • 會從 <textarea> 項目的模型產生 idname 屬性,以及資料驗證屬性。Generates the id and name attributes, and the data validation attributes from the model for a <textarea> element.

  • 提供強型別。Provides strong typing.

  • HTML 協助程式替代:Html.TextAreaForHTML Helper alternative: Html.TextAreaFor

範例:Sample:

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:The following HTML is generated:

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

標籤標籤協助程式The Label Tag Helper

  • 會針對運算式名稱產生 <label>元素的相關標籤標題和 for 屬性Generates the label caption and for attribute on a <label> element for an expression name

  • HTML 協助程式替代:Html.LabelForHTML Helper alternative: Html.LabelFor.

Label Tag Helper 相較於純粹的 HTML標籤項目,提供下列優點:The Label Tag Helper provides the following benefits over a pure HTML label element:

  • 您會自動從 Display 屬性取得描述性的標籤值。You automatically get the descriptive label value from the Display attribute. 預定的顯示名稱可能會隨著時間而改變,Display 屬性和標籤標籤協助程式的組合會在使用它的每個地方都套用 DisplayThe intended display name might change over time, and the combination of Display attribute and Label Tag Helper will apply the Display everywhere it's used.

  • 原始程式碼中較少標記Less markup in source code

  • 強型別與模型屬性。Strong typing with the model property.

範例:Sample:

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>

會為 <label> 項目產生下列 HTML:The following HTML is generated for the <label> element:

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

標籤標籤協助程式產生了 "Email" 的 for 屬性值,這是與 <input> 項目建立關聯的識別碼。The Label Tag Helper generated the for attribute value of "Email", which is the ID associated with the <input> element. 標籤協助程式會產生一致的 idfor 項目,所以能夠正確地相關聯。The Tag Helpers generate consistent id and for elements so they can be correctly associated. 在此範例中的標題來自 Display 屬性。The caption in this sample comes from the Display attribute. 如果模型未包含 Display 屬性,標題會是運算式的屬性名稱。If the model didn't contain a Display attribute, the caption would be the property name of the expression.

驗證標籤協助程式The Validation Tag Helpers

有兩個驗證標籤協助程式。There are two Validation Tag Helpers. Validation Message Tag Helper (這會顯示模型上單一屬性的驗證訊息),和 Validation Summary Tag Helper (這會顯示驗證錯誤的摘要)。The Validation Message Tag Helper (which displays a validation message for a single property on your model), and the Validation Summary Tag Helper (which displays a summary of validation errors). Input Tag Helper 會根據您模型類別上的資料註釋屬性,將 HTML5 用戶端端驗證屬性新增至輸入項目。The Input Tag Helper adds HTML5 client side validation attributes to input elements based on data annotation attributes on your model classes. 也會在伺服器上執行驗證。Validation is also performed on the server. 驗證標籤協助程式會在發生驗證錯誤時顯示這些錯誤訊息。The Validation Tag Helper displays these error messages when a validation error occurs.

驗證訊息標籤協助程式The Validation Message Tag Helper

  • 新增 HTML5data-valmsg-for="property" 屬性至 span 項目,它會將驗證錯誤訊息附加在指定模型屬性的輸入欄位。Adds the HTML5 data-valmsg-for="property" attribute to the span element, which attaches the validation error messages on the input field of the specified model property. 發生用戶端驗證錯誤時,jQuery 會在 <span> 項目顯示錯誤訊息。When a client side validation error occurs, jQuery displays the error message in the <span> element.

  • 也會在伺服器上發生驗證。Validation also takes place on the server. 用戶端可能停用 JavaScript,而一些驗證只能在伺服器端進行。Clients may have JavaScript disabled and some validation can only be done on the server side.

  • HTML 協助程式替代:Html.ValidationMessageForHTML Helper alternative: Html.ValidationMessageFor

Validation Message Tag Helper 與 HTML span 項目上的 asp-validation-for 屬性搭配使用。The Validation Message Tag Helper is used with the asp-validation-for attribute on a HTML span element.

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

驗證訊息標籤協助程式將會產生下列 HTML:The Validation Message Tag Helper will generate the following HTML:

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

您通常會在 Input 標籤協助程式之後針對相同的屬性使用 Validation Message Tag HelperYou generally use the Validation Message Tag Helper after an Input Tag Helper for the same property. 這麼做會在造成錯誤的輸入附近顯示任何驗證錯誤訊息。Doing so displays any validation error messages near the input that caused the error.

注意

您必須具有正確 JavaScript 和 jQuery 指令碼參考的檢視。You must have a view with the correct JavaScript and jQuery script references in place for client side validation. 如需詳細資訊,請參閱模型驗證See Model Validation for more information.

發生伺服器端驗證錯誤時 (例如當您有自訂伺服器端驗證或是已停用用戶端驗證時),MVC 會將該錯誤訊息放置為 <span> 項目的主體。When a server side validation error occurs (for example when you have custom server side validation or client-side validation is disabled), MVC places that error message as the body of the <span> element.

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

驗證摘要標籤協助程式The Validation Summary Tag Helper

  • 使用 asp-validation-summary 屬性設定 <div> 項目的目標Targets <div> elements with the asp-validation-summary attribute

  • HTML 協助程式替代:@Html.ValidationSummaryHTML Helper alternative: @Html.ValidationSummary

Validation Summary Tag Helper 用來顯示驗證訊息的摘要。The Validation Summary Tag Helper is used to display a summary of validation messages. asp-validation-summary 屬性值可以是下列任一項:The asp-validation-summary attribute value can be any of the following:

asp-validation-summaryasp-validation-summary 顯示的驗證訊息Validation messages displayed
ValidationSummary.AllValidationSummary.All 屬性和模型層級Property and model level
ValidationSummary.ModelOnlyValidationSummary.ModelOnly 型號Model
ValidationSummary.NoneValidationSummary.None NoneNone

範例Sample

在下列範例中,資料模型具有 DataAnnotation 屬性,這會在 <input> 元素上產生驗證錯誤訊息。In the following example, the data model has DataAnnotation attributes, which generates validation error messages on the <input> element. 在發生驗證錯誤時,驗證標籤協助程式會顯示錯誤訊息:When a validation error occurs, the Validation Tag Helper displays the error message:

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 (當模型有效時):The generated HTML (when the model is valid):

<form action="/DemoReg/Register" method="post">
  <div class="validation-summary-valid" data-valmsg-summary="true">
  <ul><li style="display:none"></li></ul></div>
  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>

選取標籤協助程式The Select Tag Helper

  • 為模型的屬性產生 select 以及相關聯的 option 項目。Generates select and associated option elements for properties of your model.

  • 有 HTML 協助程式的替代 Html.DropDownListForHtml.ListBoxForHas an HTML Helper alternative Html.DropDownListFor and Html.ListBoxFor

Select Tag Helper asp-for 指定 select 項目的模型屬性名稱,而 asp-items 指定 option 項目。The Select Tag Helper asp-for specifies the model property name for the select element and asp-items specifies the option elements. 例如:For example:

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

範例:Sample:

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

Index 方法會初始化 CountryViewModel、設定選取的國家/地區,並將其傳遞給 Index 檢視。The Index method initializes the CountryViewModel, sets the selected country and passes it to the Index view.

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

HTTP POST Index 方法會顯示選取項目:The HTTP POST Index method displays the selection:

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

Index 檢視:The Index view:

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

它會產生下列 HTML (並選取 "CA"):Which generates the following HTML (with "CA" selected):

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

注意

我們不建議使用 ViewBagViewData 搭配選取標籤協助程式。We don't recommend using ViewBag or ViewData with the Select Tag Helper. 檢視模型在提供 MVC 中繼資料方面比較強大,且通常較不容易發生問題。A view model is more robust at providing MVC metadata and generally less problematic.

asp-for 屬性值是特殊案例,不需要 Model 前置詞,其他標籤協助程式屬性則需要 (例如 asp-items)The asp-for attribute value is a special case and doesn't require a Model prefix, the other Tag Helper attributes do (such as asp-items)

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

列舉繫結Enum binding

使用 <select> 搭配 enum 屬性,並從 enum 值產生 SelectListItem 項目通常很方便。It's often convenient to use <select> with an enum property and generate the SelectListItem elements from the enum values.

範例:Sample:

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

GetEnumSelectList 方法會產生列舉的 SelectList 物件。The GetEnumSelectList method generates a SelectList object for an 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>

您可以使用 Display 屬性來標記您的列舉值清單,以取得更豐富的 UI:You can mark your enumerator list with the Display attribute to get a richer UI:

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:The following HTML is generated:

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

選項群組Option Group

當檢視模型包含一或多個 SelectListGroup 物件時,會產生 HTML <optgroup> 項目。The HTML <optgroup> element is generated when the view model contains one or more SelectListGroup objects.

CountryViewModelGroupSelectListItem 項目分組成「北美洲」和「歐洲」群組:The CountryViewModelGroup groups the SelectListItem elements into the "North America" and "Europe" groups:

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

兩個群組如下所示:The two groups are shown below:

選項群組範例

產生的 HTML:The generated 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>

多重選項Multiple select

選取標籤協助程式會自動產生 multiple = "multiple" 屬性,如果 asp-for 屬性中指定的屬性是 IEnumerableThe Select Tag Helper will automatically generate the multiple = "multiple" attribute if the property specified in the asp-for attribute is an IEnumerable. 例如,假設有以下的模型:For example, given the following model:

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

具有下列檢視:With the following view:

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

產生下列 HTML:Generates the following 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>

沒有選取項目No selection

如果您發現自己在多個頁面中使用「未指定」的選項,您可以建立範本,以避免重複 HTML:If you find yourself using the "not specified" option in multiple pages, you can create a template to eliminate repeating the HTML:

@model CountryViewModel

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

Views/Shared/EditorTemplates/CountryViewModel.cshtml 範本:The Views/Shared/EditorTemplates/CountryViewModel.cshtml template:

@model CountryViewModel

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

新增 HTML <option> 項目並不限於「沒有選取項目」的案例。Adding HTML <option> elements isn't limited to the No selection case. 例如,下列檢視和動作方法會產生類似於上述程式碼的 HTML:For example, the following view and action method will generate HTML similar to the code above:

public IActionResult IndexNone()
{
    var model = new CountryViewModel();
    model.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>

將會選取正確的 <option> 項目 (包含 selected="selected" 屬性),視目前的 Country 值而定。The correct <option> element will be selected ( contain the selected="selected" attribute) depending on the current Country value.

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>

其他資源Additional resources