加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

TagHelper是怎么实现的

发布时间:2020-12-15 21:17:12 所属栏目:asp.Net 来源:网络整理
导读:众所周知,在asp.net core中编写Razor视图的时候,用了一种新的写法-- TagHelper 那这个TagHelper是怎么回事呢? 首先来看看TagHelper的项目位置,它是位于Microsoft.AspNetCore.Mvc.TagHelpers。 如果看到project.json,可以发现,它还依赖一个比较重要的东

众所周知,在asp.net core中编写Razor视图的时候,用了一种新的写法--TagHelper

那这个TagHelper是怎么回事呢?

首先来看看TagHelper的项目位置,它是位于Microsoft.AspNetCore.Mvc.TagHelpers。

如果看到project.json,可以发现,它还依赖一个比较重要的东西Microsoft.AspNetCore.Mvc.Razor

为什么这么说呢,其实很简单,看了里面诸多TagHelper,就会发现,里面都是继承了

Microsoft.AspNetCore.Razor.TagHelpers下面的TagHelper这个抽象类。

下面就以我们天天用到的表单--FormTagHelper为例来说一下,他是怎么实现的。

首先要看看TagHelper这个抽象类:

Order { }

里面包含两比较重要的方法:Process和ProcessAsync

其实看方法名就应该知道一个是同步的方法一个是异步的方法

因为这个是输出html的方法,你说,这能不重要吗?下面来看看FormTagHelper的具体实现吧!

[HtmlTargetElement(,Attributes = ActionAttributeName)]
先来看看HtmlTargetElement这个Attribute是用来干嘛的

简单来说,它指定了我们html标签(

)以及一些相关的元素。

可以看到,诸多Attributes = XXXAttributeName,其中的XXXAttributeName是在类里面定义的变量。

ActionAttributeName = AntiforgeryAttributeName = AreaAttributeName = ControllerAttributeName = RouteAttributeName = RouteValuesDictionaryName = RouteValuesPrefix = HtmlActionAttributeName = ;

再来看看下面的图,相对比一看,是不是就很清晰了呢?

我们可以看到下面的好几个属性,如Controller,它的上面是有 HtmlAttributeName来标注的

而且这个指向的名字还是ControllerAttributeName(也就是asp-controller)。这个就是用来接收asp-controller的值。

Controller { ; ; }
相对来说,这样做只是起了个别名。
[HtmlTargetElement(,Attributes = [HtmlTargetElement(,Attributes = [HtmlTargetElement(,Attributes = [HtmlTargetElement(,Attributes = [HtmlTargetElement(,Attributes = [HtmlTargetElement(,Attributes = [HtmlTargetElement(,Attributes = RouteValuesPrefix + FormTagHelper : TagHelper
当然,我们也是可以不指定别名的,也可以不用在HtmlTargetElement指明Attributes

好比如下的代码,就可以直接用Controller

[HtmlTargetElement(    Controller { ; }

还有一个RouteValues的属性,它是一个键值对,用来存放参数的,具体可以怎么用呢?

总的来说有两种用法。可以看到它指向asp-all-route-data和asp-route-

[HtmlAttributeName(RouteValuesDictionaryName,DictionaryAttributePrefix = RouteValuesPrefix)]

用法如下:一种是用asp-all-route-data来接收一个IDictionary类型的变量,一种是通过asp-route-*的方式来接收参数*的值。

这两种写法是等价的。

下面就是FormTagHelper的构造函数和一个Generator属性

Generator = IHtmlGenerator Generator { ; }
由于在Core中,依赖注入随处可见,看到这个写法马上就是想到了这个

果不其然,发现其对应了一个实现类:DefaultHtmlGenerator。

DefaultHtmlGenerator(IAntiforgery antiforgery,IOptions TagBuilder GenerateActionLink(ViewContext viewContext, linkText, actionName, controllerName, protocol, hostname, fragment, routeValues, TagBuilder GenerateForm(ViewContext viewContext, method, TagBuilder GenerateLabel(ViewContext viewContext,ModelExplorer modelExplorer, expression, labelText, TagBuilder GenerateTextArea(ViewContext viewContext, rows, columns, TagBuilder GenerateTextBox(ViewContext viewContext, value, format, TagBuilder GenerateInput(ViewContext viewContext,InputType inputType, useViewData, isChecked, setId, isExplicitValue,IDictionary<,> TagBuilder GenerateLink( linkText, url,      }
这个类里面,我们看到了熟悉的TagBuilder,就算不去看它里面的实现都能知道它是用来干嘛的

它就是用来创建我们的Html标签,相信用过MVC的,多多少少都扩展过HtmlHelper,这是类似的。

最后,也是最最重要的重写的Process方法。

可以看到开始就判断了表单
中是否包含了action这个属性output.Attributes.ContainsName(HtmlActionAttributeName)

如果包含,就是正常的html标签。换句话说,正常的html写法和我们的TagHelper方法会有冲突,只能用其中一种。

当我们这样写的时候,编译能通过。

但是,运行的时候就会出错。

再下面的处理就是用了TagBuilder去处理了。

收集路由的数据放到一个字典中->区域是否存在->用Generator去创建form表单,返回TagBuilder对象->TagHelperOutput对象把tagbuilder的innerhtml等信息输出。

如下面的写法:

submit
生成对应的html如下:
submit
?
到这里,FormTagHelper的讲解就算是OK,至于其他的,原理都是差不多,就不再累赘了。
?
来看看,到底有多少种TagHelper(还没有部分没有列出来),以及它们包含的属性。
?

下面是我们自己写一个TagHelper——CatcherATagHelper,这个TagHelper是干什么的呢?它只是一个精简版的A标签。

[HtmlTargetElement( .Generator = UrlHelperFactory = IUrlHelperFactory UrlHelperFactory { IHtmlGenerator Generator { - Action { ; Controller { ; LinkText { ; ViewContext ViewContext { ; (Action != || Controller != urlHelper = output.TagName = output.Attributes.SetAttribute( }

?这里提供了两种写法供大家参考

一种是借助IUrlHelperFactory去生成链接

一种是借助IHtmlGenerator去生成链接

不知道大家有没有留意_ViewImports.cshtml这个文件

@addTagHelper * @inject Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration TelemetryConfiguration

这个是默认情况下帮我们添加的TagHelper

我们可以在要用到那个TagHelper的地方添加就好

With LinkText And InnerHtml Without LinkText
addTagHelper的用法如下:

@addTagHelper 你的TagHelper,你的TagHelper所在的命名空间

或者更直接

@addTagHelper *,你的TagHelper所在的命名空间

可以添加,当然也可以删除,删除是@removeTagHelper

当我们在自己的框架中完全重写了一套自己的TagHelper,那么这个时候,微软自己的TagHelper我们就可以通过下面的方法来移除了。

@removeTagHelper *,Microsoft.AspNetCore.Mvc.TagHelpers

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读