标记帮助器不仅可以给目标元素(标记)插入(或修改)属性,插入自定义的HTML内容,在某些需求中还可以替换原来标记的名称。

比如我们在使用 Blazor 时很熟悉的 Component 标记帮助器。在 Razor 文档中你将使用 <Component> 元素来设置要呈现的组件。而在实际处理时,会去掉 <Component> 元素,并呈现组件的HTML内容。

下面咱们举两个例子。

第一个比较简单,自定义的元素是 <textBox>,生成的元素是 <input type=text />。

[HtmlTargetElement("textBox", TagStructure = TagStructure.WithoutEndTag)]
public class TextInputTagHelper : TagHelper
{
public override void Process(TagHelperContext context, TagHelperOutput output)
{
// 将标记名称改为 input
output.TagName = "input";
// 设置 type 属性
output.Attributes.SetAttribute("type", "text");
}
}

这个不难理解,首先我们用的是候,在 Razor 文档使用的是元素是 <textbox>,而最后呈现出来的 HTML 是 <input> 元素。咱们就把它弄得像个控件那样用,是不是有点以前 ASP.NET 的味儿了?以前是有个前缀 asp:TextBox。

TagStructure.WithoutEndTag 的意思是指定这个标记没有结束标签,就像 <input > 或 <input />。

Razor 文档中要用 @addTagHelper 指令导入一下。

@addTagHelper *, TestApp

TestApp 是我这个程序集的名称,它导入此程序集下所有标记帮助器。

用起来也方便。

<div>
<TextBox />
</div>

运行之后,生成这样的 HTML。

<input type="text">

咱们确实可以让它更像传统 ASP.NET。

@addTagHelper *, TestApp
@tagHelperPrefix "asp:" <div>
<asp:textBox />
</div>

@tagHelperPrefix 就是为标记添加一个前缀,这里指定的是“asp:”,所以用的时候就真的捡到“童年回忆”了。想当年,ASP.NET 就是这么用的。

下面再举一例,咱们做 RadioButton(单选按钮)。选项之间互斥,同一个分组中你只能选择一项。在 HTML 中是 <input type=radio >,它没有“分组”属性,而是通过 name 属性来分组。name 相同的就是同一组,互斥。

注意的是,<input type=radio> 只显示个圈圈让你可以选中,可不包含选项文本。一般我们会给它配个 <label> 元素。然后,<label> 元素的 for 属性指向 <input> 的 id 属性。这样二者就关联了,点击<label>也能选中单选按钮。

所以,咱们实现的帮助器要生成一个<div>,里面包含<input>和<label>两个元素。

[HtmlTargetElement("radioButton", TagStructure = TagStructure.WithoutEndTag)]
public class RadioInputTagHelper : TagHelper { // 分组名称
[HtmlAttributeName("group-name")]
public string? Group { get; set; } = "radio"; // id 值
public string? Id { get; set; } = string.Empty; // 标签文本
public string? Label { get; set; } // 默认是否选中
public bool IsChecked { get; set; } = false; // 选项代表的值
public string? Value { get; set; } = string.Empty; public override void Process(TagHelperContext context, TagHelperOutput output)
{
// 修改标记名称
output.TagName = null; StringBuilder builder = new();
string html = $"""
<div>
<input type="radio" id="{Id}" name="{Group}" value="{Value}" {(IsChecked ? "checked" : "")} />
<label for="{Id}">{Label}</label>
</div>
"""; // 设置HTML内容
output.Content.SetHtmlContent(html);
}
}

默认情况下,在 Razor 文档中使用标记帮助器时,属性与.NET类属性相同。比如这个类中的 Label 属性,在Razor代码中也是Label属性。

<radioButton Label="老司机" ……>

如果你希望 HTML 属性与 .NET 属性不同,可以加上 [HtmlAttributeName] 特性,配分一个别名。

[HtmlAttributeName("group-name")]

咱们这个例子中,就为 Group 属性分配一个别名—— group-name。

<label> 元素只是呈现在HTML中的文本,让用户看,很多时候程序处理的往往不是这个,而是让标签对应一个值,即 Value 属性。Value 属性指定的值才是给程序用的。

我们来用一下这个单选按钮。

<div>
<radioButton group-name="abc" id="itme1" value="1" label="山药" is-checked="true" />
<radioButton group-name="abc" id="item2" value="2" label="鸭梨" />
<radioButton group-name="abc" id="item3" value="3" label="龙眼" />
<hr />
<radioButton group-name="good" id="item5" value="5" label="大卡车" />
<radioButton group-name="good" id="item6" value="6" label="皮卡" is-checked="true" />
<radioButton group-name="good" id="item4" value="4" label="独轮车" />
</div>

同一 group-name 下的选项是互斥关系,而不同组之间是互不影响的。

运行后,生成以下 HTML:

 <div>
<input type="radio" id="itme1" name="abc" value="1" checked />
<label for="itme1">山药</label>
</div>
<div>
<input type="radio" id="item2" name="abc" value="2" />
<label for="item2">鸭梨</label>
</div>
<div>
<input type="radio" id="item3" name="abc" value="3" />
<label for="item3">龙眼</label>
</div>
<hr />
<div>
<input type="radio" id="item5" name="good" value="5" />
<label for="item5">大卡车</label>
</div>
<div>
<input type="radio" id="item6" name="good" value="6" checked />
<label for="item6">皮卡</label>
</div>
<div>
<input type="radio" id="item4" name="good" value="4" />
<label for="item4">独轮车</label>
</div>
</div>

结果如下图所示。

接下来看第三个例子。咱们来画一个圆,标记帮助器定义一个 <circle> 元素,我们直接设置相关属性就行。比如画布宽度、画布高度、圆的圆心、半径、线的粗细。然后会生成 <canvas> 元素和相关的 js 脚本代码。

[HtmlTargetElement("Circle")]
public class CircleTagHelper : TagHelper
{
// 圆的半径
public int Radius { get; set; } // 线宽度
public int LineWidth { get; set; } // 圆心-X
public int CenterX { get; set; } // 圆心-Y
public int CenterY { get; set; } // 画布宽度
public int Width { get; set; } = 300; // 画布高度
public int Height { get; set; } = 300; public override void Process(TagHelperContext context, TagHelperOutput output)
{
// 无标记名称
output.TagName = null;
// 生成的内容
string s = $"""
<canvas id="cv" width="{Width}" height="{Height}"></canvas>
<script>
var canvas = document.getElementById('cv');
var ctx = canvas.getContext('2d');
ctx.lineWidth = {LineWidth};
ctx.strokeStyle = 'blue';
ctx.beginPath();
ctx.arc({CenterX}, {CenterY}, {Radius}, 0, 2 * Math.PI);
ctx.stroke();
</script>
""";
output.Content.SetHtmlContent(s);
}
}

TagName 设置为 null 表示咱们这个帮助器不生产标签,而是用输出字符串 s 中那段代码。即这段代码直接呈现在 HTML 文档中,外部不用其他元素包装。

来,咱们在 Razor 文档中试试看。

<Circle center-x="115" center-y="90"
width="900"
height="900"
line-width="4"
radius="70" />

绘制的圆如下图所示。

生成的 HTML 如下:

<canvas id="cv" width="900" height="900"></canvas>

<script>
var canvas = document.getElementById('cv');
var ctx = canvas.getContext('2d');
ctx.lineWidth = 4;
ctx.strokeStyle = 'blue';
ctx.beginPath();
ctx.arc(115, 90, 70, 0, 2 * Math.PI);
ctx.stroke();
</script>

用这个方法,咱们可以封装出许多图形绘制的标记,用的时候只要赋值一下属性即可,很省事的哟。

【ASP.NET Core】标记帮助器——替换元素名称的更多相关文章

  1. ASP.Net Core中使用jquery-ajax-unobtrusive替换Ajax.BeginForm

    在大潮流下,大家都在研究MVVM框架,但是做面向搜索引擎的外网项目还是得用服务器渲染. 在.Net中肯定就是用Razor模板引擎了. .Net Core断臂式重构后,很多在老得Mvc中使用得好好的一些 ...

  2. ASP.NET Core Web 应用程序系列(三)- 在ASP.NET Core中使用Autofac替换自带DI进行构造函数和属性的批量依赖注入(MVC当中应用)

    在上一章中主要和大家分享了在ASP.NET Core中如何使用Autofac替换自带DI进行构造函数的批量依赖注入,本章将和大家继续分享如何使之能够同时支持属性的批量依赖注入. 约定: 1.仓储层接口 ...

  3. ASP.NET Core Web 应用程序系列(二)- 在ASP.NET Core中使用Autofac替换自带DI进行批量依赖注入(MVC当中应用)

    在上一章中主要和大家分享在MVC当中如何使用ASP.NET Core内置的DI进行批量依赖注入,本章将继续和大家分享在ASP.NET Core中如何使用Autofac替换自带DI进行批量依赖注入. P ...

  4. ASP.NET Core利用拦截器 IActionFilter实现权限控制

    “麦荻网教系统”采用了前后端代码分离的架构,即“Miidy.Cloud.Console”站与“Miidy.Cloud.Manage”站(两个前端站)同时通过web api的方式调用“Miidy.Clo ...

  5. 重学ASP.NET Core 中的标记帮助程序

    标记帮助程序是什么 标记帮助程序使服务器端代码可以在 Razor 文件中参与创建和呈现 HTML 元素. 例如,内置的 ImageTagHelper 可以将版本号追加到图片名称.  每当图片发生变化时 ...

  6. C# -- HttpWebRequest 和 HttpWebResponse 的使用 C#编写扫雷游戏 使用IIS调试ASP.NET网站程序 WCF入门教程 ASP.Net Core开发(踩坑)指南 ASP.Net Core Razor+AdminLTE 小试牛刀 webservice创建、部署和调用 .net接收post请求并把数据转为字典格式

    C# -- HttpWebRequest 和 HttpWebResponse 的使用 C# -- HttpWebRequest 和 HttpWebResponse 的使用 结合使用HttpWebReq ...

  7. ASP.Net Core开发(踩坑)指南

    ASP.NET与ASP.NET Core很类似,但它们之间存在一些细微区别以及ASP.NET Core中新增特性的使用方法,在此之前也写过一篇简单的对比文章ASP.NET MVC应用迁移到ASP.NE ...

  8. ASP.NET Core MVC 概述

    https://docs.microsoft.com/zh-cn/aspnet/core/mvc/overview?view=aspnetcore-2.2 ASP.NET Core MVC 概述 20 ...

  9. 在Asp.NET Core中如何优雅的管理用户机密数据

    在Asp.NET Core中如何优雅的管理用户机密数据 背景 回顾 在软件开发过程中,使用配置文件来管理某些对应用程序运行中需要使用的参数是常见的作法.在早期VB/VB.NET时代,经常使用.ini文 ...

  10. 用ASP.NET Core 2.1 建立规范的 REST API -- HATEOAS

    本文所需的一些预备知识可以看这里: http://www.cnblogs.com/cgzl/p/9010978.html 和 http://www.cnblogs.com/cgzl/p/9019314 ...

随机推荐

  1. 错误:Required request parameter 'XXX' for method parameter type String is not present

    错误信息:Required request parameter 'XXX' for method parameter type String is not present 这种都是前端请求方式不同,后 ...

  2. hashlib加密模块 subprocess模块 logging日志模块

    目录 hashlib加密模块 简介 hashlib使用流程 hashilb加密模块使用说明 明文绑定密文 密文长度不变 多次传入 密文不可解密原因 加盐处理(salt) 普通加盐 动态加盐 加密实际运 ...

  3. MySQL事务(四大特性)-存储过程

    目录 一:事务 1.四大特性(ACID) 2.事物存在的必要性(真实比喻) 3.如何使用事务 4.开启事务-回滚-确认 二:事务案例实战 1.模拟消费 2.创建 3.插入数据 4.开启事务 5.修改操 ...

  4. 李宏毅机器学习笔记:从0到写AI

    part1.基本介绍 1.机器学习的三个任务 一般情况下,我们在机器学习中有三个基本任务,分别是Regression Classification和Structured Regression是计算数值 ...

  5. Python启动HTTP服务进行文件传输

    有时候局域网共享个东西不方便,尤其在服务器上的时候,总不能先下载下来,再上传上去吧,于是经常在这台机器用python起个http服务,然后去另一台机器直接访问,一来二去,妥试不爽,特进行一下分离 py ...

  6. [OpenCV实战]14 使用OpenCV实现单目标跟踪

    目录 1 背景 1.1 什么是目标跟踪 1.2 跟踪与检测 2 OpenCV的目标跟踪函数 2.1 函数调用 2.2 函数详解 2.3 综合评价 3 参考 在本教程中,我们将了解OpenCV 3中引入 ...

  7. [常用工具] live555的搭建

    live555是一个为流媒体提供解决方案的跨平台的C++开源项目,它实现了对标准流媒体传输协议如RTP/RTCP.RTSP.SIP等的支持.使用live555可以播放rtsp流.本文主要是在linux ...

  8. 10分钟做好 Bootstrap Blazor 的表格组件导出 Excel/Word/Html/Pdf

    上篇: Bootstrap Blazor 实战 通用导入导出服务(Table组件) 1.新建工程 新建工程b14table dotnet new blazorserver -o b14table 将项 ...

  9. MAC上好用的解压工具

    macOS:11.1 想在 macOS 上打开一个压缩文件,有原生的归档实用工具或 BetterZip.Keka.The Unarchiver 等诸多选择.最近,又有国内独立开发者为我们带来了一款新作 ...

  10. hashlib 模块 subprocess 模块 logging日志模块

    今日内容 hashlib加密模块 1.何为加密 将明文数据处理成密文数据 让人看不懂 2.为什么加密 保证数据的安全 3.如何判断数据是否加密的 一串没有规律的字符串(数字.字母.符号) 4.密文的长 ...