.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 != 0))))
        {
            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 > 0))
        {
            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 }"/>
 
 
 
 
时间: 2024-10-08 22:44:49

.Net Core-TagHelpers的相关文章

Professional C# 6 and .NET Core 1.0 - Chapter 41 ASP.NET MVC

What's In This Chapter? Features of ASP.NET MVC 6 Routing Creating Controllers Creating Views Validating User Inputs Using Filters Working with HTML and Tag Helpers Creating Data-Driven Web Applications Implementing Authentication and Authorization W

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

目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 在Asp.net Core VS2015中,我们发现还有很多不太简便的地方,比如右击添加视图,转到试图页等功能图不见了,虽然我们可以通过工具栏的自定义命令,把这两个右击菜单添加上,但是貌似是灰色的不能用. 其实,这样也好,通过手动创建,更让我们深刻的理解MVC以及路由之间的关系,很多人认为底层的东西是高大上的,比如一提到汇编,很多人感觉牛的不行不行的,其实术业有专攻,做程序的感觉搞核电的很牛,搞核电的同样也感觉做程序的很牛

Asp.net Core 创建 Areas[区域]

在Asp.net Core VS2015中,我们发现还有很多不太简便的地方,比如右击添加视图,转到试图页等功能图不见了,虽然我们可以通过工具栏的自定义命令,把这两个右击菜单添加上,但是貌似是灰色的不能用. 其实,这样也好,通过手动创建,更让我们深刻的理解MVC以及路由之间的关系,很多人认为底层的东西是高大上的,比如一提到汇编,很多人感觉牛的不行不行的,其实术业有专攻,做程序的感觉搞核电的很牛,搞核电的同样也感觉做程序的很牛,但是通过手动的创建MVC以及路由,除了让我们深刻的理解MVC之外,也在一

NET Core 的 Views

NET Core 十种方式扩展你的 Views 原文地址:http://asp.net-hacker.rocks/2016/02/18/extending-razor-views.html作者:Jürgen Gutsch翻译:杨晓东(Savorboard) 现在,已经有很多种方式来扩展Razor视图了,我们循循渐进,先从最简单的开始.如果你之前熟悉MVC5(以及之前的MVC)中的视图的话,有一部分你应该已经很熟悉了.在新的ASP.NET Core 中,那些你熟悉的方式有一部分仍然能用,只是Cor

初识ASP.NET Core 1.0

本文将对微软下一代ASP.NET框架做个概括性介绍,方便大家进一步熟悉该框架. 在介绍ASP.NET Core 1.0之前有必要澄清一些产品名称及版本号.ASP.NET Core1.0是微软下一代ASP.NET 框架,在这之前ASP.NET版本稳定在ASP.NET  4.6,对应的.NET Framework版本为.net 4.6.1. 曾经一段时间微软将下一代ASP.NET 命名为ASP.NET 5和MVC 6,在ASP.NET 5 is dead – Introducing ASP.NET

asp.net core下的使用Application Insights

在Visudio Studio中,新建asp.net core可以内置Application Insights.Application Insights可以帮助我们分应web应用的性能,以至于我们来优化我们的应用,本文是step by step篇. 代码端 新建 asp.net core项目(asp.net core 1.1版本) 第三步配置设置,可以选择自己azure上的资源组. (注:目前asp.net core新建项目是1.0版本,可以在nuget中升级成1.1版本) 设置Starup.c

ASP.NET MVC Core的TagHelper (高级特性)

这篇博文ASP.NET MVC Core的TagHelper(基础篇)介绍了TagHelper的基本概念和创建自定义TagHelper的方式,接着继续介绍一些新的看起来比较高级的特性.(示例代码紧接着上一遍博文) 一.使用自定义的标记元素 之前基础篇介绍的TagHelper的功能是给已有的HTML元素提供一个自定义的属性标记,然后服务器认出这个标记后,将标记转化成最终的HTML.这里将要介绍的功能是,定义个全新的Tag,看起来跟普通的HTML元素一样.是不是觉得很熟悉呢(前提是你用过Angula

[转].net core 通过ViewComponent封装控件 左侧菜单

本文转自:http://www.cnblogs.com/BenDan2002/p/6224816.html 我们在.net core中还使用了ViewComponent方式生成控件.ViewComponent也是asp.net core的新特性,是对页面部分的渲染,以前PartialView的功能,可以使用ViewComponent来实现. View Component包含2个部分,一个是类(继承于ViewComponent),和它返回的结果Razor视图(和普通的View视图一样). 我们还是

Bare metal APIs with ASP.NET Core MVC(转)

ASP.NET Core MVC now provides a true "one asp.net" framework that can be used for building both APIs and websites. But what if you only want to build an API? Most of the ASP.NET Core MVC tutorials I've seen advise using the Microsoft.AspNetCore.

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

原文:Razor Syntax Reference 作者:Taylor Mullen.Rick Anderson 翻译:刘怡(AlexLEWIS) 校对:何镇汐 什么是 Razor? Razor 是一种基于服务器端代码的可以转换为网页的标记语法.Razor 语法包括 Razor 标记.C# 和 HTML 组成.包含 Razor 的文件通常后缀名为 .cshtml . 渲染 HTML Razor 的默认语言是 HTML.从 Razor 渲染为 HTML 和直接一个 HTML 文件没啥区别,这种 R