.net core Razor視圖的TagHelper使用方法介紹


TagHelper

TagHelper是ASP.NET 5的一個新特性。也許在你還沒有聽說過它的時候, 它已經在技術人員之間引起了大量討論,甚至有一部分稱它為服務器控件的回歸。實際上它只不過是一個簡化版本,把HTML和服務器內容混合在一起,沒有控件生命周期,狀態保持和事件。它不像服務器控件那樣,對頁面所有內容都具有訪問權限。它只能訪問到自己所生成的內容。

在 Razor 文件中,Tag Helpers 能夠讓服務端代碼參與創建和渲染 HTML 元素。
Tag Helpers通過豐富的智能感知環境來創建 HTML 和 Razor 標記,為我們提供了友好的開發體驗,同時讓生成的代碼更加高效、可靠,可維護。

 

Form TagHelper

直接舉例

<form asp-controller="Demo" asp-action="Register" method="post"> </form>

生成的HTML

<form method="post" action="/Demo/Register"> <input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>" /> </form>

MVC 運行時會根據 Form Tag Helper 的屬性 asp-controllerasp-action 生成 action的屬性值。

命名路由

通過asp-route可以讓下面的表單使用路由規則中name為register的路由。

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

生成的HTML:

<form asp-controller="Account" asp-action="Login" method="post" class="form-horizontal" role="form"> <!-- Input and Submit elements --> </form>

Input TagHelper

作用:

  1. 為 asp-for 屬性中指定的表達式名稱生成 id 和 name 屬性。

  2. 基於模型類型和應用在模型屬性上的 Tpye 特性來設置 HTML type 的屬性值。

  3. 如果 HTML type 屬性已被指定,則不會覆蓋它。

  4. 根據應用在模型屬性上的 驗證 特性生成 HTML5 驗證屬性。

上面第2條說到TagHelper基於 .NET 類型和特性來設置 HTML type 屬性。以下是常見的 .NET 類型和特性生成出的 HTML 類型

.Net類型生成的HTML類型:

.Net類型 Input類型
Bool type=”checkbox”
String type=”text”
DateTime type=”datetime”
Byte type=”number”
Int type=”number”
Single, Double type=”number”

.Net特性生成的HTML類型:

Attribute Input Type
[EmailAddress] type=”email”
[Url] type=”url”
[HiddenInput] type=”hidden”
[Phone] type=”tel”
[DataType(DataType.Password)] type=”password”
[DataType(DataType.Date)] type=”date”
[DataType(DataType.Time)] type=”time”

例子:

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 :

<form method="post" action="/Demo/RegisterInput"> Email: <input type="email" data-val="true" data-val-email="The Email Address field is not a valid e-mail 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>

asp-for 屬性值是一個 ModelExpression 同時也是 lambda 表達式右邊的部分。因此,不需要使用 Model 前綴

定位子屬性

asp-for可以通過視圖模型的屬性路徑定位到子屬性。

類代碼:

//類A public class AddressViewModel { public string AddressLine { get; set; } } //類B中嵌套了類A public class RegisterAddressViewModel { public string Email { get; set; } [DataType(DataType.Password)] public string Password { get; set; } public AddressViewModel Address { get; set; } }

視圖代碼:

@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.AddressLine" /><br /> <button type="submit">Register</button> </form>

 

asp-for是不需要model前綴的,所以直接可以與model中的email等屬性綁定。

對於子屬性AddressLine,我們可以通過Address.AddressLine來綁定。

TagHelper驗證

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

 

通常在模型屬性相同的 Input Tag Helper后面使用 Validation Message Tag Helper 。這樣可以在發生驗證錯誤的 input 旁邊顯示錯誤信息。

HTML Helper 替代選項: Html.ValidationMessageFor()

Select TagHelper

Select TagHelper 的 asp-for 為 select 元素指定模型的屬性名稱,而 asp-items 則指定 option 元素。

類代碼:

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" }, }; } public IActionResult Index() { var model = new CountryViewModel(); model.Country = "CA"; return View(model); }

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>

 

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

上面asp-for指定的模型類型是單值類型,但如果指定的模型換成一個 IEnumerable 類型, Select Tag Helper 將會在HTML中自動生成 multiple = “multiple”。

注意:只要asp-for 是一個特例,不需要 Model 前綴。

選項分組

當選項分組時,會生成 HTML < optgroup > 元素:

public class CountryViewModelGroup { public CountryViewModelGroup() { var AmericaGroup = new SelectListGroup { Name = "America" }; var EuropeGroup = new SelectListGroup { Name = "Europe" }; public string Country { get; set; } public List<SelectListItem> Countries { get; } = new List<SelectListItem> { new SelectListItem { Value = "CAN", Text = "Canada", Group = AmericaGroup }, new SelectListItem { Value = "US", Text = "USA", Group = AmericaGroup }, new SelectListItem { Value = "FR", Text = "France", Group = EuropeGroup }, new SelectListItem { Value = "ES", Text = "Spain", Group = EuropeGroup }, }; } }

其余操作與上面Select Tag Helper類似。。。

Select TagHelper的枚舉綁定

public enum CountryEnum { Mexico, [Display(Name = "United States of America")] USA, Canada, France, Germany, Spain } public class CountryEnumViewModel { public CountryEnum EnumCountry { get; set; } }

 

視圖:

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

生成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">Mexico</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>

 

Html Helper與 Input Tag Helper 功能的異同

  1. Html.TextBox、Html.TextBoxFor、Html.Editor 和 Html.EditorFor 有着與 Input Tag Helper 重復的功能。

  2. Input Tag Helper 會自動設置 type 屬性,而Html.TextBox 和 Html.TextBoxFor 則不會。

  3. Html.Editor 和 Html.EditorFor 會處理集合、復雜對象以及模版,而Input Tag Helper 則不會。

  4. Input Tag Helper 、Html.EditorFor 和 Html.TextBoxFor 是強類型的,但是Html.TextBox 和 Html.Editor 則不是。

  5. HTML Helper 的Html.TextAreaFor、Html.LabelFor 與Textarea Tag Helper、 Label Tag Helper 類似。

  6. Tag Helper和 HTML Helpers 相比,生成的標記干凈得多而且更容易閱讀,編輯和維護。

自定義Tag

創建類繼承自TagHelper可以讓我們擴展tagHelper的功能:

<email>Support</email>
  • 1
//[HtmlTargetElement(Attributes = "email")] public class EmailTagHelper : TagHelper { private const string EmailDomain = "contoso.com"; public override void Process(TagHelperContext context, TagHelperOutput output) { output.TagName = "a"; // Replaces <email> with <a> tag var address = MailTo + "@" + EmailDomain; output.Attributes.SetAttribute("href", "mailto:" + address); output.Content.SetContent(address); } }

 

Description:

  1. Tag helper 使用以目標元素名作為根類名,在這個例子中, EmailTagHelper 的根名稱是 email ,因此 TagName的默認值就是email。

  2. 重寫 Process 方法可以控制 Tag Helper 在執行過程中的行為。 TagHelper 類同樣提供了相同參數的異步版本(ProcessAsync)。

  3. 類名后綴TagHelper是非必需的,但它被認為是最佳慣例約定。

  4. 為使自定義的TagHelper在Razor中可用,需要在Views/_ViewImports.cshtml 文件中通過addTagHelper指令添加包含自定義TagHelper的命名空間。

  5. [HtmlTargetElement] 屬性傳遞一個屬性參數,指定為任何 HTML 元素包含名為 “bold” 的 HTML 屬性。例如:同時使用[HtmlTargetElement(“email”)]和[HtmlTargetElement(Attributes = “email”)],bold 標簽和bold 屬性都會被匹配。

//異步Process public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { output.TagName = "a"; // Replaces <email> with <a> tag var content = await output.GetChildContentAsync(); var target = content.GetContent() + "@" + EmailDomain; output.Attributes.SetAttribute("href", "mailto:" + target); output.Content.SetContent(target); }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM