请选择 进入手机版 | 继续访问电脑版

马上加入IBC程序猿 各种源码随意下,各种教程随便看! 注册 每日签到 加入编程讨论群

C#教程 ASP.NET教程 C#视频教程程序源码享受不尽 C#问题入口 ASP.NET问题入口

【C#问题提交】 社群合作 申请版主 程序开发 【远程协助】 每天乐一乐 每日签到 【承接毕业设计】 面试-葵花宝典下载

官方一群:

官方二群:

查看: 31|回复: 0

ASP.NET Core 3.0 : 二十五. TagHelper

[复制链接]
  • TA的每日心情
    开心
    14 小时前
  • 签到天数: 1486 天

    [LV.10]以坛为家III

    1541

    主题

    3452

    帖子

    9万

    积分

    管理员

    IBC编程社区-原道楠

    Rank: 9Rank: 9Rank: 9

    积分
    96031

    推广达人突出贡献优秀版主荣誉管理论坛元老

    发表于 2019-9-26 09:20:26 | 显示全部楼层 |阅读模式

    马上加入IBC,查看更多教程

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x

      什么是TagHelper?这是ASP.NET Core 中新出现的一个名词,它的作用是使服务器端代码可以在Razor 文件中参与创建和出现HTML 元素。(ASP.NET Core 系列目次)

    一、概述

      上面的解释有点拗口?那么换一个名词,HtmlHelper各人都知道吧,在ASP.NET Core中,TagHelper雷同HtmlHelper,但可以说是后来居上而胜于蓝。那么TagHelper的作用也就大概明确了吧。

    起首通过一个例子看一下TagHelper是怎么利用的,看看它和HtmlHelper有什么区别。新建一个Book类:

    1. public class Book
    2. {
    3. [Display(Name = "编号")]
    4. public string Code { get; set; }
    5. [Display(Name = "名称")]
    6. public string Name { get; set; }
    7. }
    复制代码

    新建对应的Controller和Action:

    1. public class BookController : Controller
    2. {
    3. // GET: /<controller>/
    4. public IActionResult Index()
    5. {
    6. return View(new Book() { Code = "001", Name = "ASP" });
    7. }
    8. }
    复制代码

    末了就是View了:

    1. @model Book
    2. @{
    3. Layout = null;
    4. }
    5. @Html.LabelFor(m => m.Name)
    6. @Html.EditorFor(m => m.Name)
    7. <br />
    8. <label asp-for="Name"></label>
    9. <input asp-for="Name" />
    复制代码

    这里分别通过HtmlHelper和TagHelper两种方式实现了一个文本和输入框的表现。查看网页源代码,可以看到二者天生的HTML如下:

    1. <label for="Name">Name</label>
    2. <input class="text-box single-line" id="Name" name="Name" type="text" value="ASP" />
    3. <br/>
    4. <label for="Name">Name</label>
    5. <input type="text" id="Name" name="Name" value="ASP" />
    复制代码

    现在看起来二者差不多,从工作量上来看也是区别不大。现在功能实现了,必要做一些样式处置处罚。简单举个例子,现在盼望Book的编号(Code)对应的label的颜色设置为赤色,界说了一个css如下:

    1. <style type="text/css">
    2. .codeColor {
    3. color:red;
    4. }
    5. </style>
    复制代码

    然后准备把这个样式应用到label上,这时如果是HtmlHelper就很有可能会被问:“class写在哪”,估计许多多少人都被问过。然后我们告诉他可以如许写:

    1. @Html.LabelFor(m=>m.Name,new {@class="codeColor"})
    复制代码

    前端工程师添加后达到了想要的效果,但同时表现记不住这个写法,下次可能还会问。

    如果是TagHelper就方便了,告诉他可以像平时给Html的标签添加class一样操纵即可,也就是:

    1. <label asp-for="Name" class="codeColor"></label>
    复制代码

    前端工程师表现这种写法“真是太友好了”。同样对于Form及验证,比力一下两种写法的差别,HtmlHelper版:

    1. @using (Html.BeginForm("Index", "Home", FormMethod.Post)){
    2. @Html.LabelFor(m => m.Code)
    3. @Html.EditorFor(m => m.Code) @Html.ValidationMessageFor(m => m.Code) <input type="submit" value="提交" />
    4. }
    复制代码

    TagHelper版:

    1. <form asp-action="Index" asp-controller="Home" method="post">
    2. <label asp-for="Code"></label>
    3. <input asp-for="Code" />
    4. for="Code">
    5. <input type="submit" value="提交" />
    6. </form>
    复制代码

    二、自界说TagHelper

    现在有如许的需求,用于表现Book的编号的label不止要添加名为codeColor的css样式,还要给书的编号自动添加一个前缀,例如“BJ”。

    对于如许的需求,盼望可以通过一个简单的标记,然后由TagHelper自动实现。例如:

    1. <label show-type="bookCode">1001</label>
    复制代码

    自界说了一个属性“show-type”,用于标识这个label的表现种别,“1001”为假定的图书编号。通过如许的设置方式,未来如果需求有变革,必要对编号的表现做更多的修饰,只需修改对应的TagHelper即可,而页面部门不必要做任何调整。

    体系提供了方便的自界说TagHelper的方式,就是继续体系提供的TagHelper类,并重写它的Process/ProcessAsync方法,例如下面的例子:

    1. public class LabelTagHelper : TagHelper
    2. {
    3. public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    4. {
    5. if (output.Attributes.TryGetAttribute("show-type", out TagHelperAttribute showTypeAttribute))
    6. {
    7. if (showTypeAttribute.Value.ToString().Equals("bookCode"))
    8. {
    9. output.Attributes.SetAttribute("class", "codeColor");
    10. string content = output.Content.IsModified ? output.Content.GetContent() : (await output.GetChildContentAsync()).GetContent(); ;
    11. output.Content.SetContent("BJ" + content);
    12. }
    13. }
    14. }
    15. }
    复制代码

    起首判断label是否被设置了show-type="bookCode",然后获取当前label的Content内容,将其添加前缀“BJ”后作为此label的Content的新内容。注意一下Content的获取方式,如果它没有被修改,凭感觉直接通过output.Content.GetContent()获取到的内容是空的。

    访问index页面,可以看到改标签已被处置处罚,如下图:

    092205lkrbx5brv33e47xx.png

    备注:a.关于获取show-type的值,还可以有其他方式,下文会讲到。

    b.从规范化定名的角度,建议将自界说的TagHelper其定名为XXXagHelper如许的格式。

    三、TagHelper的注册

    TagHelper自界说之后必要将其注册一下,否则它是不会收效的。打开_ViewImports.cshtml,默认为:

    1. @using TagHelperDemo
    2. @using TagHelperDemo.Models
    3. @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
    复制代码

    在最下面添加一条

    1. @addTagHelper *, TagHelperDemo
    复制代码

    末了添加的这一句话是什么意思呢?也就是将步伐集TagHelperDemo(即第二个参数)中的全部TagHelper(第一个参数为“*”,即全部)全部启用。如果还界说了一个PasswordTagHelper,但只想只添加LabelTagHelper,可以如许写:

    1. @addTagHelper TagHelperDemo.TagHelpers. LabelTagHelper, TagHelperDemo
    复制代码

    如果想添加全部自界说的TagHelper,但要去除LabelTagHelper呢?

    那么可以先添加全部,再去除这个LabelTagHelper。

    1. @addTagHelper *, TagHelperDemo
    2. @removeTagHelper TagHelperDemo.TagHelpers. LabelTagHelper, TagHelperDemo
    复制代码

    四、TagHelper的作用范围

    在项目中,可能不止利用label标签来表现Book的Code,另有可能会是p、span等范例的标签,现在的需求是,无论是上述哪一种标签,都要实现添加css和前缀的功能。

    现在将index.cshtml中新增一个p标签如下:

    1. <p show-type="bookCode">1002</p>
    复制代码

    访问这个页面发现1002未被处置处罚。这是由于我们界说的TagHelper名为LabelTagHelper,在默认的环境下只会处置处罚label标签。固然也可以做特殊设置,例如下面代码的写法:

    1. [HtmlTargetElement("p")]
    2. public class LabelTagHelper : TagHelper
    3. {
    4. //代码省略
    5. }
    复制代码

    通过“[HtmlTargetElement("p")]”指定本TagHelper只能被利用于p标签。再次访问此页面,发现p标签被处置处罚了,而label未被处置处罚。这分析如许的显式指定的优先级要高于默认的名称匹配。除了设置指定标签,还可以有一些其他的辅助设置:

    1. [HtmlTargetElement("p", Attributes = "show-type", ParentTag = "div")]
    2. public class LabelTagHelper : TagHelper
    复制代码

    可以如许写,会匹配p标签,要求该标签拥有show-type属性,并且父标签为div。这几个条件是“and”的关系。如果还想匹配label标签,可以添加对label的设置,例如下面代码如许:

    1. [HtmlTargetElement("p", Attributes = "show-type", ParentTag = "div")]
    2. [HtmlTargetElement("label", Attributes = "show-type", ParentTag = "div")]
    3. public class LabelTagHelper : TagHelper
    复制代码

    这两个HtmlTargetElement的关系是“or”。通过如许的设置,可以极大的缩小目的标签的范围。

    但是如许设置之后,这个TagHelper的名字再叫LabelTagHelper就不符合了,例如可以改为BookCodeTagHelper,最终代码如下:

    1. [HtmlTargetElement("p", Attributes = "show-type", ParentTag = "div")]
    2. [HtmlTargetElement("label", Attributes = "show-type", ParentTag = "div")]
    3. public class BookCodeTagHelper : TagHelper
    4. {
    5. public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    6. {
    7. if (output.Attributes.TryGetAttribute("show-type", out TagHelperAttribute showTypeAttribute))
    8. {
    9. if (showTypeAttribute.Value.ToString().Equals("bookCode"))
    10. {
    11. output.Attributes.SetAttribute("class", "codeColor");
    12. string content = output.Content.IsModified ? output.Content.GetContent() :
    13. (await output.GetChildContentAsync()).GetContent(); ;
    14. output.Content.SetContent("BJ" + content);
    15. }
    16. }
    17. }
    18. }
    复制代码

    如果想使个别Html标签屏蔽TagHelper的作用,可以利用“!”。例如下面两个标签:

    1. <!label show-type="bookCode">1001</label>
    复制代码

    五、自界说标签

    上一节最终形成了一个名为BookCodeTagHelper的TagHelper,我们知道LabelTagHelper是可以按名称默认匹配label标签的,那么是否可以自界说一个BookCode标签呢?在index.cshtml中添加如许的代码:

    1. <BookCode>1003</BookCode>
    复制代码

    由于自界说bookcode标签的目的就是专门表现Book的Code,所以也不必添加show-type属性了。然后修改BookCodeTagHelper,修改后的代码如下:

    1. public class BookCodeTagHelper : TagHelper
    2. {
    3. public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    4. {
    5. output.Attributes.SetAttribute("class", "codeColor");
    6. string content = output.Content.IsModified ? output.Content.GetContent() :
    7. (await output.GetChildContentAsync()).GetContent(); ;
    8. output.Content.SetContent("BJ" + content);
    9. }
    10. }
    复制代码

    去掉了两个HtmlTargetElement设置并取消了对show-type的判断,访问index页面查看新建的bookcode标签是否会被处置处罚,效果是没有被处置处罚。这是为什么呢?

    这是由于TagHelper会将接纳Pascal 巨细写格式的类和属性名将转换为各自相应的短横线格式。即“BookCode”对应“book-code”,获取标签的属性值,同样遵循如许的规则。所以将标签改为如下写法即可:

    1. <book-code>1003</book-code>
    复制代码

    再次运行测试,发现这个新标签被成功处置处罚。查看网页源代码,被处置处罚后的Html代码是如许的:

    1. <book-code class="codeColor">TJ1003</book-code>
    复制代码

    如果想将其改变为label,可以在BookCodeTagHelper中通过指定TagName实现:

    1. public class BookCodeTagHelper : TagHelper
    2. {
    3. public Book Book { get; set; }
    4. public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    5. {
    6. output.TagName = "label";
    7. output.Attributes.SetAttribute("class", "codeColor");
    8. string content = output.Content.IsModified ? output.Content.GetContent() :
    9. (await output.GetChildContentAsync()).GetContent(); ;
    10. output.Content.SetContent(Book.Prefix + content);
    11. }
    12. }
    复制代码

    六、TagHelper与页面之间的数据转达

    如果现在的新需求是图书编码的前缀不再固定为“BJ”了,必要在标签中界说,例如如许:

    1. <book-code prefix="SH">1003</book-code>
    复制代码

    必要获取prefix的值,在上面的例子中接纳的是TryGetAttribute方法,实在另有简单的方式,修改BookCodeTagHelper,代码如下:

    1. public class BookCodeTagHelper : TagHelper
    2. {
    3. public string Prefix { get; set; }
    4. public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    5. {
    6. output.Attributes.SetAttribute("class", "codeColor");
    7. string content = output.Content.IsModified ? output.Content.GetContent() :
    8. (await output.GetChildContentAsync()).GetContent(); ;
    9. output.Content.SetContent(Prefix + content);
    10. }
    11. }
    复制代码

    标签中的prefix的值会自动赋值给BookCodeTagHelper.Prefix,是不是更方便了。那么如果是Model中的值呢?如果Book类有一个属性“public string Prefix { get; set; } ”,这和传入一个字符串没什么区别,那么可以如许写:

    1. <book-code prefix="@Model.Prefix">1003</book-code>
    复制代码

    这种传值方式不止是支持字符串,将Model整体传入也是支持的,将标签修改如下:

    1. <book-code book="@Model">1003</book-code>
    复制代码

    修改BookCodeTagHelper代码:

    1. public class BookCodeTagHelper : TagHelper
    2. {
    3. public Book Book { get; set; }
    4. public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    5. {
    6. output.Attributes.SetAttribute("class", "codeColor");
    7. string content = output.Content.IsModified ? output.Content.GetContent() :
    8. (await output.GetChildContentAsync()).GetContent(); ;
    9. output.Content.SetContent(Book.Prefix + content);
    10. }
    11. }
    复制代码

    七、取消标签输出

    前面的几个例子都是对满意条件的标签的修改,TagHelper也可以取消对应标签的输出,例如存在如许一个标签:

    1. <div simple-type="Simple1"></div>
    复制代码

    如果不想让它出现在天生的Html中,可以如许处置处罚:

    1. [HtmlTargetElement("div",Attributes = "simple-type")]
    2. public class Simple1TagHelpers : TagHelper
    3. {
    4. public string SimpleType { get; set; }
    5. public override void Process(TagHelperContext context, TagHelperOutput output)
    6. {
    7. if (SimpleType.Equals("Simple1")) //可以是其他一些判断规则
    8. {
    9. output.SuppressOutput();
    10. }
    11. }
    12. }
    复制代码

    八、TagBuilder

    在TagHelper中,可以用TagBuilder来辅助天生标签,例如存在如下两个div:

    1. <div simple-type="Simple2"></div>
    2. <div simple-type="Simple3"></div>
    复制代码

    想在div中添加Html元素可以如许写:

    1. [HtmlTargetElement("div",Attributes = "simple-type")]
    2. public class Simple1TagHelpers : TagHelper
    3. {
    4. public string SimpleType { get; set; }
    5. public override void Process(TagHelperContext context, TagHelperOutput output)
    6. {
    7. if (SimpleType.Equals("Simple2"))
    8. {
    9. output.Content.SetHtmlContent("<p>Simple2</p>");
    10. }
    11. else if (SimpleType.Equals("Simple3"))
    12. {
    13. var p = new TagBuilder("p");
    14. p.InnerHtml.Append("Simple3");
    15. output.Content.SetHtmlContent(p);
    16. }
    17. }
    18. }
    复制代码

    通过TagBuilder天生了一个新的p标签,并将它插入到div中。







    来源:https://www.cnblogs.com/FlyLolo/archive/2019/09/25/ASPNETCore_25.html
    C#论坛 www.ibcibc.com IBC编程社区
    C#
    C#论坛
    IBC编程社区
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则