写在开头
前面介绍了TagHelper的基本概念和内嵌的TagHelpers,想必大家对TagHelper都有一定的了解。TagHelper看上去有点像WebControl,但它不同于WebControl,没有复杂的生命周期、状态保持、服务器事件以及较高权限,它只能修改自己Tag的内容。有时觉得它更像angular写出来的一个widget,有自己特有的Tag,并对其进行解析生成出widget ui和启动脚本,但是它具有更高的权限,能访问服务器端信息。
在这章,将要介绍如何自定义TagHelper,考虑到内容比较多,会分成几个小章节来介绍。
TagHelper基类
通过查看内嵌的TagHelpers的源码,发现这些TagHelpers都继承自Microsoft.AspNet.Razor.Runtime.TagHelpers.TagHelper抽象类,而这个类又实现了接口Microsoft.AspNet.Razor.Runtime.TagHelpers.ITagHelper。这个接口是TagHelper最底层的接口,
/// <summary>
/// Contract used to filter matching HTML elements.
/// </summary>
public interface ITagHelper
{
/// <summary>
/// 获取实现ITagHelper接口的类的解析顺序.
/// 值小的先用该类来解析。
/// </summary>
int Order { get; } /// <summary>
/// 根据所给参数context和output异步解析实现ITagHelper的当前类.
/// </summary>
/// <param name="context">当前HTML Tag的相关信息</param>
/// <param name="output">用于生成HTML Tag的HTML元素.</param>
/// <returns>用于更新output的Task实例.</returns>
Task ProcessAsync(TagHelperContext context, TagHelperOutput output);
}
TagHelper类,主要实现了上面接口,添加了一个同步方法来解析当前类,定义如下:
/// <summary>
/// Class used to filter matching HTML elements.
/// </summary>
public abstract class TagHelper : ITagHelper
{
public virtual int Order { get; } = 0; //同步解析当前TagHelper
public virtual void Process(TagHelperContext context, TagHelperOutput output)
{
} //异步解析当前TagHelper
public virtual async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
Process(context, output);
}
}
一般自定义TagHelper时,只需要设计的类继承于TagHelper类,重载Process方法,根据context,设置output输出html元素和脚本即可。
TagHelper类名
自定义的TagHelper类名格式为***TagHelper,其中省略部分***就是该TagHelper应用的Tag。比如我们定义:
public class MyTagHelper: TagHelper
{
....
}
那么页面上所有Tag是my都会进入到这个类来解析,注意Tag名要是小写。
如果***中包括好几个大写字母,那么对于的Tag名是将大写字母变小写前面加上"-",如果大写字母在第一个位置,那么只需要改成小写,前面不需要加“-”。比如
public class MyFirstOneTagHelper: TagHelper
{
...
}
那么作用的Tag是
<my-first-one ... ></my-first-one>
我们还可以在类上添加TargetElementAttribute来设置作用的Tag,比如定义如下的类时,其作用的Tag名为my。
[TargetElement("my")]
public class MyFirstOneTagHelper: TagHelper
{
...
}
待续...