.net core Razor视图的Tag Helper

Tag Helper

在 Razor 文件中,Tag Helpers 能够让服务端代码参与创建和渲染 HTML 元素。
Tag Helpers通过丰富的智能感知环境来创建 HTML 和 Razor 标记,为我们提供了友好的开发体验,同时让生成的代码更加高效、可靠,可维护。
Tag Helpers的内容比较多,特地整理一下。。。

Form Tag Helper

直接举例

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

form>

生成的HTML

<form method="post" action="/Demo/Register">

  <input name="__RequestVerificationToken" type="hidden" value="" />
 form>

MVC 运行时会根据 Form Tag Helper 的属性 asp-controllerasp-action 生成 action的属性值。

使用命名路由

通过asp-route可以让下面的表单使用路由规则中name为register的路由。

<form asp-route="register" method="post">
    
form>

生成的HTML:

<form asp-controller="Account" asp-action="Login"
  method="post" class="form-horizontal" role="form">
  
form>

Input Tag Helper

作用:

  1. 为 asp-for 属性中指定的表达式名称生成 id 和 name 属性。

  2. 基于模型类型和应用在模型属性上的 Tpye 特性来设置 HTML type 的属性值。

  3. 如果 HTML type 属性已被指定,则不会覆盖它。

  4. 根据应用在模型属性上的 验证 特性生成 HTML5 验证属性。

上面第2条说到Tag Helper基于 .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">Registerbutton>
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">Registerbutton>
  <input name="__RequestVerificationToken" type="hidden" value="" />
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">Registerbutton>
form>

asp-for是不需要model前缀的,所以直接可以与model中的email等属性绑定。

对于子属性AddressLine,我们可以通过Address.AddressLine来绑定。

Tag Helper验证

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

Select Tag Helper 的 asp-for 为 select 元素指定模型的属性名称,而 asp-items 则指定 option 元素。

类代码:

public class CountryViewModel
{
    public string Country { get; set; }

    public List Countries { get; } = new List
    {
        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">Registerbutton>
form>

生成Html:

method="post" action="/">
"__RequestVerificationToken" type="hidden" value="" />

上面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 Countries { get; } = new List
         {            
             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 Tag Helper的枚举绑定

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()"> >
    select> 
    <br /><button type="submit">Registerbutton>
form>

生成HTML:

method="post" action="/Home/IndexEnum">
"__RequestVerificationToken" type="hidden" value="" />

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>Supportemail>
//[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  with  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  with  tag
    var content = await output.GetChildContentAsync();
    var target = content.GetContent() + "@" + EmailDomain;
    output.Attributes.SetAttribute("href", "mailto:" + target);
    output.Content.SetContent(target);
}

参考

ASP.NET Core 中文文档 第四章 MVC(3.4)如何使用表单:
http://www.cnblogs.com/dotNETCoreSG/p/aspnetcore-4_3_4-working-with-forms.html
ASP.NET Core 中文文档 第四章 MVC(3.6.1 )Tag Helpers 介绍:
http://www.cnblogs.com/dotNETCoreSG/p/aspnetcore-4_3_6_1-introduction-to-tag-helpers.html
ASP.NET Core 中文文档 第四章 MVC(3.6.2 )自定义标签辅助类(Tag Helpers):
http://www.cnblogs.com/dotNETCoreSG/p/aspnetcore-4_3_6_2-tag-helpers-authoring.html

你可能感兴趣的:(.Net,.NET,Core,MVC)