zoukankan      html  css  js  c++  java
  • 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; }
    }
    View Code
    首先,这个类继承自抽象类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; }
    }
    View Code
    TagHelper又继承自ITagHelper接口
    public interface ITagHelper
    {
        // Methods
        void Init(TagHelperContext context);
        Task ProcessAsync(TagHelperContext context, TagHelperOutput output);
    
        // Properties
        int Order { get; }
    }
    View Code
    这个接口只有两个方法,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);
            }
        }
    }
    View Code
    ,发现这个方法主要就是根据我们填写的属性、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 }"/>
    
     
     
     
     
  • 相关阅读:
    BZOJ5296 [CQOI2018] 破解D-H协议 【数学】【BSGS】
    Codeforces963C Frequency of String 【字符串】【AC自动机】
    Codeforces962F Simple Cycles Edges 【双连通分量】【dfs树】
    Hello World
    Codeforces963C Cutting Rectangle 【数学】
    BZOJ5203 [NEERC2017 Northern] Grand Test 【dfs树】【构造】
    20160422 --Switch…case 总结; 递归算法
    20160421字符串类型;日期时间类型数学类型
    20160420冒泡排序和查找
    20160419 while练习,复习
  • 原文地址:https://www.cnblogs.com/zh1990/p/5671229.html
Copyright © 2011-2022 走看看