ASP.Net Core-TagHelpers
当我们新建了一个.Net Core类型的Project时,我们会看到页面上有类似于这样的代码:

当我们运行项目,查看源代码会发现,浏览器中的就是Html代:

那么,为什么我们在页面写的代码会转化为html标签呢?接下来我们就来探索这个秘密。
当我们在vs中把鼠标放到这样的元素上时发现这样的元素都是一个Microsoft.AspNetCore.Mvc.TagHelpers命名空间下的对象,我们通过Reflector查看a标签的对象AnchorTagHelper
[HtmlTargetElement("a", Attributes="asp-action"), HtmlTargetElement("a", Attributes="asp-controller"), HtmlTargetElement("a", Attributes="asp-area"), HtmlTargetElement("a", Attributes="asp-fragment"), HtmlTargetElement("a", Attributes="asp-host"), HtmlTargetElement("a", Attributes="asp-protocol"), HtmlTargetElement("a", Attributes="asp-route"), HtmlTargetElement("a", Attributes="asp-all-route-data"), HtmlTargetElement("a", Attributes="asp-route-*")]
public class AnchorTagHelper : TagHelper
{
// Fields
private IDictionary<string, string> _routeValues;
private const string ActionAttributeName = "asp-action";
private const string AreaAttributeName = "asp-area";
private const string ControllerAttributeName = "asp-controller";
private const string FragmentAttributeName = "asp-fragment";
private const string HostAttributeName = "asp-host";
private const string Href = "href";
private const string ProtocolAttributeName = "asp-protocol";
private const string RouteAttributeName = "asp-route";
private const string RouteValuesDictionaryName = "asp-all-route-data";
private const string RouteValuesPrefix = "asp-route-";
// Methods
public AnchorTagHelper(IHtmlGenerator generator);
public override void Process(TagHelperContext context, TagHelperOutput output);
// Properties
[HtmlAttributeName("asp-action")]
public string Action { get; set; }
[HtmlAttributeName("asp-area")]
public string Area { get; set; }
[HtmlAttributeName("asp-controller")]
public string Controller { get; set; }
[HtmlAttributeName("asp-fragment")]
public string Fragment { get; set; }
protected IHtmlGenerator Generator { [CompilerGenerated] get; }
[HtmlAttributeName("asp-host")]
public string Host { get; set; }
public override int Order { get; }
[HtmlAttributeName("asp-protocol")]
public string Protocol { get; set; }
[HtmlAttributeName("asp-route")]
public string Route { get; set; }
[HtmlAttributeName("asp-all-route-data", DictionaryAttributePrefix="asp-route-")]
public IDictionary<string, string> RouteValues { get; set; }
[HtmlAttributeNotBound, ViewContext]
public ViewContext ViewContext { get; set; }
}
首先,这个类继承自抽象类TagHelper
public abstract class TagHelper : ITagHelper
{
// Methods
protected TagHelper();
public virtual void Init(TagHelperContext context);
public virtual void Process(TagHelperContext context, TagHelperOutput output);
public virtual Task ProcessAsync(TagHelperContext context, TagHelperOutput output); // Properties
public virtual int Order { [CompilerGenerated] get; }
}
TagHelper又继承自ITagHelper接口
public interface ITagHelper
{
// Methods
void Init(TagHelperContext context);
Task ProcessAsync(TagHelperContext context, TagHelperOutput output); // Properties
int Order { get; }
}
这个接口只有两个方法,Init和ProcessAsync,我们也许会猜到,转化的过程就是通过这两个方法来转化的。没错,你猜对了。
我们回到AnchorTagHelper类中,查看Process方法:
public override void Process(TagHelperContext context, TagHelperOutput output)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
if (output == null)
{
throw new ArgumentNullException("output");
}
if (output.Attributes.ContainsName("href"))
{
if ((((this.Action != null) || (this.Controller != null)) || ((this.Area != null) || (this.Route != null))) || (((this.Protocol != null) || (this.Host != null)) || ((this.Fragment != null) || (this.RouteValues.Count != ))))
{
throw new InvalidOperationException(Resources.FormatAnchorTagHelper_CannotOverrideHref("<a>", "asp-action", "asp-controller", "asp-area", "asp-route", "asp-protocol", "asp-host", "asp-fragment", "asp-route-", "href"));
}
}
else
{
TagBuilder builder;
IDictionary<string, object> routeValues = null;
if ((this._routeValues != null) && (this._routeValues.Count > ))
{
routeValues = new Dictionary<string, object>(this._routeValues.Count, StringComparer.OrdinalIgnoreCase);
foreach (KeyValuePair<string, string> pair in this._routeValues)
{
routeValues.Add(pair.Key, pair.Value);
}
}
if (this.Area != null)
{
if (routeValues == null)
{
routeValues = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
}
routeValues["area"] = this.Area;
}
if (this.Route == null)
{
builder = this.Generator.GenerateActionLink(this.ViewContext, string.Empty, this.Action, this.Controller, this.Protocol, this.Host, this.Fragment, routeValues, null);
}
else
{
if ((this.Action != null) || (this.Controller != null))
{
throw new InvalidOperationException(Resources.FormatAnchorTagHelper_CannotDetermineHrefRouteActionOrControllerSpecified("<a>", "asp-route", "asp-action", "asp-controller", "href"));
}
builder = this.Generator.GenerateRouteLink(this.ViewContext, string.Empty, this.Route, this.Protocol, this.Host, this.Fragment, routeValues, null);
}
if (builder != null)
{
output.MergeAttributes(builder);
}
}
}
,发现这个方法主要就是根据我们填写的属性、ViewContext(View上下文)、routeValue(路由信息)来生成Html标签,主要方法就是在GenerateRouteLink生成一个TagBuilder类型的对象,再通过output.MergeAttributes(builder);生成TagHelperOutput类型的对象。
那么,我们在页面上写的属性是怎么与AnchorTagHelper中的属性关联的呢?
我们可以看这个类中的属性,每个属性前面都有一个[HtmlAttributeName("asp-action")] ,标记这个属性和我们页面上写的asp-**属性关联的。
综上,如果我们不清楚具体的某个TagHelper有哪些属性,我们可以通过反编译查看,当然没必要。我们只要通过VS直接通过智能感知系统就可以点出来这些属性。
我们还可以自定义自己的Tag,只要继承自ITagHelper,实现方法就可以
public class WebsiteInformationTagHelper : TagHelper
{
public WebsiteContext Info { get; set; } public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.TagName = "section";
output.PostContent.SetContent(string.Format(
"<p><strong>Version:</strong> {0}</p>" + Environment.NewLine +
"<p><strong>Copyright Year:</strong> {1}</p>" + Environment.NewLine +
"<p><strong>Approved:</strong> {2}</p>" + Environment.NewLine +
"<p><strong>Number of tags to show:</strong> {3}</p>" + Environment.NewLine,
Info.Version.ToString(),
Info.CopyrightYear.ToString(),
Info.Approved.ToString(),
Info.TagsToShow.ToString()));
output.SelfClosing = false;
}
}
<website-information info="new WebsiteContext {
Version = new Version(1, 1),
CopyrightYear = 1990,
Approved = true,
TagsToShow = 30 }"/>
ASP.Net Core-TagHelpers的更多相关文章
- ASP.NET Core 中文文档 第四章 MVC(3.2)Razor 语法参考
原文:Razor Syntax Reference 作者:Taylor Mullen.Rick Anderson 翻译:刘怡(AlexLEWIS) 校对:何镇汐 什么是 Razor? Razor 是一 ...
- ASP.NET Core 中文文档 第四章 MVC(3.3)布局视图
原文:Layout 作者:Steve Smith 翻译:娄宇(Lyrics) 校对:孟帅洋(书缘) 视图(View)经常共享视觉元素和编程元素.在本篇文章中,你将学习如何在你的 ASP.NET 应用程 ...
- ASP.NET Core 中文文档 第四章 MVC(3.6.1 )Tag Helpers 介绍
原文:Introduction to Tag Helpers 作者:Rick Anderson 翻译:刘浩杨 校对:高嵩(Jack) 什么是 Tag Helpers? Tag Helpers 提供了什 ...
- ASP.NET Core 中文文档 第四章 MVC(3.6.2 )自定义标签辅助类(Tag Helpers)
原文:Authoring Tag Helpers 作者:Rick Anderson 翻译:张海龙(jiechen) 校对:许登洋(Seay) 示例代码查看与下载 从 Tag Helper 讲起 本篇教 ...
- Asp.Net Core 项目实战之权限管理系统(5) 用户登录
0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...
- ASP.NET Core MVC TagHelper实践HighchartsNET快速图表控件-开源
ASP.NET Core MVC TagHelper最佳实践HighchartsNET快速图表控件支持ASP.NET Core. 曾经在WebForms上写过 HighchartsNET快速图表控件- ...
- 【无私分享:ASP.NET CORE 项目实战(第九章)】创建区域Areas,添加TagHelper
目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 在Asp.net Core VS2015中,我们发现还有很多不太简便的地方,比如右击添加视图,转到试图页等功能图不见了,虽然我 ...
- [asp.net core]定义Tag Helpers
原文地址 https://docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/authoring Getting started wi ...
- [asp.net core] Tag Helpers 简介(转)
原文地址 https://docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/intro What are Tag Helpers? ...
- ASP.NET Core 十种方式扩展你的 Views
原文地址:http://asp.net-hacker.rocks/2016/02/18/extending-razor-views.html 作者:Jürgen Gutsch 翻译:杨晓东(Savor ...
随机推荐
- linux page cache和buffer cache
主要区别是,buffer cache缓存元信息,page cache缓存文件数据 buffer 与 cache 是作为磁盘文件缓存(磁盘高速缓存disk cache)来使用,主要目的提高文件系统系性能 ...
- haproxy 规则匹配到了就停止,不会继续匹配下一个
acl url_web_wwm path_beg -i /scan use_backend zjtest7_com if url_web_wwm acl url_static path_end .ht ...
- string.Join和string.Concat的区别
源自Difference between String.Join() vs String.Concat() With .NET 4.0, String.Join() uses StringBuilde ...
- Android开发UI之ListView中的Button点击设置
在ListView的Item中,如果有Button控件,那么要实现Button和Item点击都有响应,可以将Item的Layout中Button的focusable属性设为false,然后设置layo ...
- poj 2993 Emag eht htiw Em Pleh(模拟)
题目:http://poj.org/problem?id=2993 题意:和2996反着 #include <iostream> #include<cstdio> #inclu ...
- 51nod水题记
妈呀51nod已经刷不动了又开始跟bzoj一样总是得看题解了...那么发一下总结吧... 1051:最大子矩阵 #include<cstdio> #include<cstring&g ...
- Samba 安全漏洞
漏洞名称: Samba 安全漏洞 CNNVD编号: CNNVD-201403-239 发布时间: 2014-03-17 更新时间: 2014-03-17 危害等级: 中危 漏洞类型: 信任管理 威 ...
- Imageview使用记录
1. imageView清除背景 原文网址:http://blog.csdn.net/lzq1039602600/article/details/40393591 两种清除 imageView的背景 ...
- Spring AOP--返回通知,异常通知和环绕通知
在上篇文章中学习了Spring AOP,并学习了前置通知和后置通知.地址为:http://www.cnblogs.com/dreamfree/p/4095858.html 在本文中,将继续上篇的学习, ...
- Google Gson解析Json数据应用实例
转自:http://lixigao449778967.blog.163.com/blog/static/24985164201269105928783/ 1.需要的Jar包 1) Google Gso ...