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

.net core Razor视图的TagHelper使用方法介绍的更多相关文章

  1. ASP.NET Core Razor 视图导入 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core Razor 视图导入 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core Razor 视图导入 上一章节我们介绍了视图起始页,学习 ...

  2. ASP.NET Core Razor 视图起始页 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core Razor 视图起始页 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core Razor 视图起始页 上一章节中我们介绍了布局视图, ...

  3. ASP.NET Core Razor 视图组件

    视图组件简介 在新的ASP.NET Core MVC中,视图组件类似于局部视图,但它们更强大.视图组件不使用模型绑定,仅依赖于您在调用时提供的数据. 视图组件特性: 呈现页面响应的某一部分而不是整个响 ...

  4. ASP.NET Core - Razor页面之Handlers处理方法

    简介 在前一篇文章中,我们讨论了Razor页面.今天我们来谈谈处理方法(Handlers). 我们知道可以将代码和模型放在 .cshtml 文件里面或与 .cshtml 匹配的 .cshtml.cs ...

  5. ASP.NET Core Razor 视图预编译、动态编译

    0x01 前言 ASP.NET Core在默认发布情况下,会启动预编译将试图编译成xx.Views.dll,也许在视图中打算修改一处很细小的地方我们需要再重新编译视图进行发布.下面我将从 ASP.NE ...

  6. YbSoftwareFactory 代码生成插件【二十五】:Razor视图中以全局方式调用后台方法输出页面代码的三种方法

    上一篇介绍了 MVC中实现动态自定义路由 的实现,本篇将介绍Razor视图中以全局方式调用后台方法输出页面代码的三种方法. 框架最新的升级实现了一个页面部件功能,其实就是通过后台方法查询数据库内容,把 ...

  7. C# -- HttpWebRequest 和 HttpWebResponse 的使用 C#编写扫雷游戏 使用IIS调试ASP.NET网站程序 WCF入门教程 ASP.Net Core开发(踩坑)指南 ASP.Net Core Razor+AdminLTE 小试牛刀 webservice创建、部署和调用 .net接收post请求并把数据转为字典格式

    C# -- HttpWebRequest 和 HttpWebResponse 的使用 C# -- HttpWebRequest 和 HttpWebResponse 的使用 结合使用HttpWebReq ...

  8. ASP.Net Core Razor+AdminLTE 小试牛刀

    AdminLTE 一个基于 bootstrap 的轻量级后台模板,这个前端界面个人感觉很清爽,对于一个大后端的我来说,可以减少较多的时间去承担前端的工作但又必须去独立去完成一个后台系统开发的任务,并且 ...

  9. ASP.NET Core MVC的Razor视图中,使用Html.Raw方法输出原生的html

    我们在ASP.NET Core MVC项目中,有一个Razor视图文件Index.cshtml,如下: @{ Layout = null; } <!DOCTYPE html> <ht ...

随机推荐

  1. Java中快捷键

    Fond表示字体 size表示字号 IDEA的基本配置 IDEA中常用的快捷键 Intellij IDEA基本快捷键 Ctrl+G 跳转到指定行 Ctrl+F4 关闭当前编辑页面 Ctrl+F 搜索 ...

  2. 如何用ps简单快速扣头发丝

    好久不用PS抠图,今天接到一个小任务,换背景,以前一直用通道的办法,但用通道比较费劲,发现一个更简单的办法,就是用快速蒙版+调整边缘. 这张是原图: 1.先用快速蒙版制作选取(Q) 再按Q,退出快速蒙 ...

  3. 【译】使用 Flutter 实现跨平台移动端开发

    作者: Mike Bluestein   | 原文地址:[https://www.smashingmagazine.com/2018/06/google-flutter-mobile-developm ...

  4. 20164305 徐广皓 Exp2 后门原理与实践

    实验内容 (1)使用netcat获取主机操作Shell,cron启动 (2)使用socat获取主机操作Shell, 任务计划启动 (3)使用MSF meterpreter(或其他软件)生成可执行文件, ...

  5. python&JSONP(初级篇)

    JSONP产生背景 1.跨域的安全限制都是对浏览器端来说的,服务器端是不存在跨域安全限制的. 2.浏览器的同源策略限制从一个源加载的文档或脚本与来自另一个源的资源进行交互. 3.如果协议,端口和主机对 ...

  6. Depp Learning note Day1

    1.softmax函数的优化来防止溢出 2.np.argmax()函数的使用 返回值为数组中最大值的索引 a = [1, 2, 3, 4, 3, 7] print(np.argmax(a)) 若np. ...

  7. Beta 冲刺(7/7)

    目录 摘要 团队部分 个人部分 摘要 队名:小白吃 组长博客:hjj 作业博客:beta冲刺(7/7) 后敬甲(组长) 过去两天完成了哪些任务 ppt制作 视频拍摄 接下来的计划 准备答辩 还剩下哪些 ...

  8. SQL解析

    private static String getCountSql(String sql) { return "select count(*) from "+cutOrderByO ...

  9. 收集Typecho 0.9还能用的插件

    收集Typecho 0.9还能用的插件 名称 描述 版本 作者 BaiduSubmit 百度结构化插件 for Typecho 0.5.2 老高 CateFilter 首页过滤指定分类 1.2.1 R ...

  10. vscode插件解析-BookMark

    BookMark (书签):在编辑器中标记行并轻松跳转到它们. commands 书签:Toggle   标记/取消标记带书签的行 书签:Jump to Next  将光标向前移动到下面的书签 书签: ...