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. 前端安全类——CSRF/XSS

    CSRF 概念:跨站请求伪造 全称:Cross-site request forgery 攻击原理:网站中某一个接口存在漏洞,用户在注册网站登录过 防御措施: 1.Token验证:引诱链接只会自动携带 ...

  2. 一封来自恶魔的挑战邀请函,那些你见过或者没见过的C语言指针都在这里了

    前言 相信大多数的同学都是第一门能接触到语言是C/C++,其中的指针也是比较让人头疼的部分了,因为光是指针都能专门出一本叫<C和指针>的书籍,足见指针的强大.但如果不慎误用指针,这些指针很 ...

  3. 自制stm32板子无法烧录程序的问题

    自己画的stm32板子一开始出现了无法烧录程序的情况,主要表现为在点击load图标后出现了Stlink connect error!Target dll has been concelled的窗口.在 ...

  4. Supervisor的安装以及使用

    1.supervisor的介绍 Supervisor 是用Python开发的一个client/server服务,是Linux/Unix系统下的一个进程管理工具,不支持Windows系统,通过配置可以实 ...

  5. 多个Fragment在一个activity中通过按钮的展示方法

    fragment使用方法 1. 创建主Mainactivity extends AppCompatActivity 2. Oncreate & setContentView 3. 完成XML的 ...

  6. Flask-Web开发(第一部分)

    1.Jinja2变量过滤器: safe 渲染值时不转义capitalize 把值的首字母转换成大写,其他字母转换成小写lower 把值转换成小写形式upper 把值转换成大写形式title 把值中每个 ...

  7. C. Neko does Maths(数论 二进制枚举因数)

     题目链接:https://codeforces.com/contest/1152/problem/C 题目大意:给你a和b,然后让你找到一个k,使得a+k和b+k的lcm. 学习网址:https:/ ...

  8. leveldb(ssdb)性能、使用场景评估

    最近有个业务场景存储压力很大,写远远大于读,读也集中在最近写入,想想这不很适合采用leveldb存储么.leveldb的话好像用ssdb比较多,花了两天时间就ssdb简单做下测试,以下总结. ssdb ...

  9. mysql 经纬度求距离

    SELECT id,lng,lat,ROUND(6378.138*2*ASIN(SQRT(POW(SIN((lat1*PI()/180-lat*PI()/180)/2),2)+COS(lat1*PI( ...

  10. 推荐前端开发手机调试打印神器console.log()

    下面说的这个插件很牛,相信很多人都不知道,但找问题的时候很需要,直接上干货如下: vConsole:一个轻量.可拓展.针对手机网页的前端开发者调试面板. 下载 vConsole 的最新版本.(不要直接 ...