当我们新建了一个.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的更多相关文章

  1. ASP.NET Core 中文文档 第四章 MVC(3.2)Razor 语法参考

    原文:Razor Syntax Reference 作者:Taylor Mullen.Rick Anderson 翻译:刘怡(AlexLEWIS) 校对:何镇汐 什么是 Razor? Razor 是一 ...

  2. ASP.NET Core 中文文档 第四章 MVC(3.3)布局视图

    原文:Layout 作者:Steve Smith 翻译:娄宇(Lyrics) 校对:孟帅洋(书缘) 视图(View)经常共享视觉元素和编程元素.在本篇文章中,你将学习如何在你的 ASP.NET 应用程 ...

  3. ASP.NET Core 中文文档 第四章 MVC(3.6.1 )Tag Helpers 介绍

    原文:Introduction to Tag Helpers 作者:Rick Anderson 翻译:刘浩杨 校对:高嵩(Jack) 什么是 Tag Helpers? Tag Helpers 提供了什 ...

  4. ASP.NET Core 中文文档 第四章 MVC(3.6.2 )自定义标签辅助类(Tag Helpers)

    原文:Authoring Tag Helpers 作者:Rick Anderson 翻译:张海龙(jiechen) 校对:许登洋(Seay) 示例代码查看与下载 从 Tag Helper 讲起 本篇教 ...

  5. Asp.Net Core 项目实战之权限管理系统(5) 用户登录

    0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...

  6. ASP.NET Core MVC TagHelper实践HighchartsNET快速图表控件-开源

    ASP.NET Core MVC TagHelper最佳实践HighchartsNET快速图表控件支持ASP.NET Core. 曾经在WebForms上写过 HighchartsNET快速图表控件- ...

  7. 【无私分享:ASP.NET CORE 项目实战(第九章)】创建区域Areas,添加TagHelper

    目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 在Asp.net Core VS2015中,我们发现还有很多不太简便的地方,比如右击添加视图,转到试图页等功能图不见了,虽然我 ...

  8. [asp.net core]定义Tag Helpers

    原文地址 https://docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/authoring Getting started wi ...

  9. [asp.net core] Tag Helpers 简介(转)

    原文地址 https://docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/intro What are Tag Helpers? ...

  10. ASP.NET Core 十种方式扩展你的 Views

    原文地址:http://asp.net-hacker.rocks/2016/02/18/extending-razor-views.html 作者:Jürgen Gutsch 翻译:杨晓东(Savor ...

随机推荐

  1. 反汇编(Disassembler) iPhone

    什么是反汇编? 反汇编就是把可执行的二进制文件转为汇编代码,进而可以研究该程序.IDA Pro Adv v5.2 版本起已直接支援 iPhone ARM 代码的静态反汇编分析.IDA Pro Adv ...

  2. JavaScript DOM高级程序设计 5动态修改样式和层叠样式表2--我要坚持到底!

    把样式置于DOM脚本之外 style属性 我们可以这样设置前景色之类的属性: element.style.color='red'; 也可以使用下面的代码设置背景颜色: element.style.ba ...

  3. Android之AndroidManifest.xml文件解析

    转自:Android学习笔记之AndroidManifest.xml文件解析 一.关于AndroidManifest.xml AndroidManifest.xml 是每个android程序中必须的文 ...

  4. 不输入密码ssh直接登录阿里云Linux主机

    服务器环境:阿里云云服务器,Linux版本 - CentOS 客户端环境:Mac OSX Terminal 注意: 如果有3个账号都要无密码登录, 则3个账号都要这么操作 在Terminal中用ssh ...

  5. Python:urllib和urllib2的区别

    urllib和urllib2都是处理url请求的两个模块,但是相互之间存在不同,不能相互取代 urllib2可以接受一个Reuqest类的实例来设置URL请求的headers,urllib仅可以接受U ...

  6. Python中的函数对象与闭包

    函数在Python中是第一类对象,可以当做参数传递给其他函数,放在数据结构中,以及作为函数的返回结果. 下面的例子为接受另外一个函数作为输入并调用它 #foo.py def callf(func): ...

  7. FJOI2007轮状病毒

    不会推公式…… 不会基尔霍夫矩阵…… 不会matrix—tree定理…… 膜拜vfleaking大神…… 题解:http://z55250825.blog.163.com/blog/static/15 ...

  8. Java String 的equals, == , hascode的区别

    1.equals 和 == ==在java中是比较引用的,即在内存中的地址.而String的equals()是比较字符串的内容 http://blog.csdn.net/barryhappy/arti ...

  9. JQuery focus()

    跳转到登陆页面时可以使用focus方法 <input name="login_account"id="login_account"class=" ...

  10. web前端优化-温故知新系列(1)

    有关web前端优化的博文,博客园中有许多网友的博客中都有介绍,而且详细.精准.楼主打算写这个博客,算是对自己一年工作来的一个总结和积累有些知识从别的地方拷贝过来的,但是都审查过. 引言: 1. 慢的页 ...