.NET Core第15天_MVC的TagHeper使用_微软Web应用框架中前端部分的演进

微软Web应用框架中前端部分的演进

微软於Web应用框架中前端部分
做的三次大变革

.net Webform框架的控件(控制项)
由於高度封装再加上各自有各自事件生命周期控管,导致能调整的弹性差,Server Side处理偏过多导致效能上也不佳。

https://ithelp.ithome.com.tw/upload/images/20210916/20107452t1itw3NMnU.png

.net MVC框架的HTML Helper
别於webform采用中度封装,但本质仍是透过C#在进行封装。
https://ithelp.ithome.com.tw/upload/images/20210916/20107452ibQqguILgC.png

.net core MVC框架的 Tag Helper (标签协助程序)
自过去前两个框架推出由於平台局限性,使微软又推出一套可跨平台的框架,
当中也顺势将web应用相关框架移植进来,於MVC部分又多设计出Tag Helper语法使用上跟原生html没有太大差异,唯独多封装一个asp-for来指定Model物件属性值。
(当然之前.net mvc遗留的 html helper仍可使用。)
https://ithelp.ithome.com.tw/upload/images/20210916/20107452mnIPkYcil2.png
藉此可以观察微软从本来封装程自家的风格趋向於原始html标签风格

TahHelper预设放置於
Microsoft.AspNetCore.Mvc.TagHelpers的namespace
在一开始专案配置也会被全域性引入
https://ithelp.ithome.com.tw/upload/images/20210916/201074523zZSR3QNyd.png

BaseClass TagHelper衍生出
LabelTagHelper
InputTagHelper
LinkTagHelper
SelectTagHelper
....

而只要在html属性中有asp-for则代表目前使用的是TagHelper衍生的相关Helper Class
asp-for必须要与从Controller传递到View的ViewModel Class中Property 名称一致
https://ithelp.ithome.com.tw/upload/images/20210916/20107452UBa5fqRz9J.png

InputTagHelper原始码

#region 组件 Microsoft.AspNetCore.Mvc.TagHelpers, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
// C:\Program Files\dotnet\packs\Microsoft.AspNetCore.App.Ref\5.0.0\ref\net5.0\Microsoft.AspNetCore.Mvc.TagHelpers.dll
#endregion

using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;

namespace Microsoft.AspNetCore.Mvc.TagHelpers
{
    //
    // 摘要:
    //     Microsoft.AspNetCore.Razor.TagHelpers.ITagHelper implementation targeting <input>
    //     elements with an asp-for attribute.
    [HtmlTargetElement("input", Attributes = "asp-for", TagStructure = TagStructure.WithoutEndTag)]
    public class InputTagHelper : TagHelper
    {
        //
        // 摘要:
        //     Creates a new Microsoft.AspNetCore.Mvc.TagHelpers.InputTagHelper.
        //
        // 参数:
        //   generator:
        //     The Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator.
        public InputTagHelper(IHtmlGenerator generator);

        public override int Order { get; }
        //
        // 摘要:
        //     Gets the Microsoft.AspNetCore.Mvc.Rendering.ViewContext of the executing view.
        [HtmlAttributeNotBound]
        [ViewContext]
        public ViewContext ViewContext { get; set; }
        //
        // 摘要:
        //     An expression to be evaluated against the current model.
        [HtmlAttributeName("asp-for")]
        public ModelExpression For { get; set; }
        //
        // 摘要:
        //     The format string (see https://msdn.microsoft.com/en-us/library/txafckwd.aspx)
        //     used to format the Microsoft.AspNetCore.Mvc.TagHelpers.InputTagHelper.For result.
        //     Sets the generated "value" attribute to that formatted string.
        //
        // 备注:
        //     Not used if the provided (see Microsoft.AspNetCore.Mvc.TagHelpers.InputTagHelper.InputTypeName)
        //     or calculated "type" attribute value is checkbox, password, or radio. That is,
        //     Microsoft.AspNetCore.Mvc.TagHelpers.InputTagHelper.Format is used when calling
        //     Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator.GenerateTextBox(Microsoft.AspNetCore.Mvc.Rendering.ViewContext,Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExplorer,System.String,System.Object,System.String,System.Object).
        [HtmlAttributeName("asp-format")]
        public string Format { get; set; }
        //
        // 摘要:
        //     The type of the <input> element.
        //
        // 备注:
        //     Passed through to the generated HTML in all cases. Also used to determine the
        //     Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator helper to call and the default
        //     Microsoft.AspNetCore.Mvc.TagHelpers.InputTagHelper.Format value. A default Microsoft.AspNetCore.Mvc.TagHelpers.InputTagHelper.Format
        //     is not calculated if the provided (see Microsoft.AspNetCore.Mvc.TagHelpers.InputTagHelper.InputTypeName)
        //     or calculated "type" attribute value is checkbox, hidden, password, or radio.
        [HtmlAttributeName("type")]
        public string InputTypeName { get; set; }
        //
        // 摘要:
        //     The name of the <input> element.
        //
        // 备注:
        //     Passed through to the generated HTML in all cases. Also used to determine whether
        //     Microsoft.AspNetCore.Mvc.TagHelpers.InputTagHelper.For is valid with an empty
        //     Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression.Name.
        public string Name { get; set; }
        //
        // 摘要:
        //     The value of the <input> element.
        //
        // 备注:
        //     Passed through to the generated HTML in all cases. Also used to determine the
        //     generated "checked" attribute if Microsoft.AspNetCore.Mvc.TagHelpers.InputTagHelper.InputTypeName
        //     is "radio". Must not be null in that case.
        public string Value { get; set; }
        //
        // 摘要:
        //     Gets the Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator used to generate
        //     the Microsoft.AspNetCore.Mvc.TagHelpers.InputTagHelper's output.
        protected IHtmlGenerator Generator { get; }

        //
        // 例外状况:
        //   T:System.InvalidOperationException:
        //     Thrown if Microsoft.AspNetCore.Mvc.TagHelpers.InputTagHelper.Format is non-null
        //     but Microsoft.AspNetCore.Mvc.TagHelpers.InputTagHelper.For is null.
        //
        // 备注:
        //     Does nothing if Microsoft.AspNetCore.Mvc.TagHelpers.InputTagHelper.For is null.
        public override void Process(TagHelperContext context, TagHelperOutput output);
        //
        // 摘要:
        //     Gets an <input> element's "type" attribute value based on the given modelExplorer
        //     or Microsoft.AspNetCore.Mvc.ViewFeatures.InputType.
        //
        // 参数:
        //   modelExplorer:
        //     The Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExplorer to use.
        //
        //   inputTypeHint:
        //     When this method returns, contains the string, often the name of a Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata.ModelType
        //     base class, used to determine this method's return value.
        //
        // 传回:
        //     An <input> element's "type" attribute value.
        protected string GetInputType(ModelExplorer modelExplorer, out string inputTypeHint);
    }
}

TagHelper的管控

TagHelper的作用范围
主要是透过@addTagHelper、@removeTagHelper、! (退出字元)这三个指令做控制
预设在使用所有View之前会先被执行到一个导入的View文件
主要用於一个全域统一导入namespae的文件(_ViewImport.cshtml)
https://ithelp.ithome.com.tw/upload/images/20210916/20107452IKVr94WPiL.png

检视(视图)导入,会直接把该引入的相关指令套用到所有视图中,使我们不需要每一个View都在重复添加共用指令。

@addTagHelper
预设就会被放置并写在ViewImport.cshtml中,若注解掉则TagHelper就无法再所有View使用。

这里准备好StudentController的action method Index跟相应的View
沿用上次的 Student ViewModel
https://ithelp.ithome.com.tw/upload/images/20210916/20107452nqwIJoQAnR.png

可以看到效果有出现从控制器传到View的属性资料
这里更改一下View改为透过TagHelper方式
https://ithelp.ithome.com.tw/upload/images/20210916/20107452ry6nNAFOAi.png

将@addTagHelper注解後运行效果

https://ithelp.ithome.com.tw/upload/images/20210916/20107452CRA54vJtcL.png

@removeTagHelper
就是去关闭TagHelper
https://ithelp.ithome.com.tw/upload/images/20210916/20107452W0GEuBGx18.png

通常也可以选择在特定某一个View上去做关闭不使用TagHelper
可以去把_ViewImport.cshtml copy一份放到特定某个Controller的Folder下来做特定控制器下的TagHelper开关,该层级会覆盖掉上一层目录的_ViewImport.cshtml设定。

! (退出字元)
在某一个View中一部份code要用TagHelper一部份则不使用,这时可以透过!来控管。
用!可以抉择html元素是否进用TagHelper程序。
https://ithelp.ithome.com.tw/upload/images/20210916/20107452BSXSP3FFla.png

@tagHelperPrefix

某些公司或是开发team通常都很喜欢有自定义的前缀
有点类似自己封装某个套件或控制项感觉
通常我们在.net core mvc也可自订前缀
在_ViewImport.cshtml可进行全域设定
https://ithelp.ithome.com.tw/upload/images/20210916/201074525Zg27061ZQ.png

这边要注意当你有指定prefix後原先的原生tag若没有家前缀就会失效不会跟属性值绑定
因此会要统一都改加上有钱缀版本的tag。

在Tag属性中使用C#程序码

若有需要在属性中做一些状态切换逻辑
要注意透过Razor混和C#在前端的code要写的位置必须在属性的值,也就是等号右侧(後面)的地方,不可以直接写在属性定义的地方也就是等号左侧。

比方是否超过20岁的年龄判断是否可以点送出按钮
https://ithelp.ithome.com.tw/upload/images/20210916/20107452IbGNZT3743.png

https://ithelp.ithome.com.tw/upload/images/20210916/20107452nkLB9ColmZ.png

Student 的 Index.cshtml

@model StudentViewModel
<div>
    <p>@Model.Name</p>
    <p>@Model.Age</p>
</div>

<div>
    <input type="text" asp-for="Name" />
    <input type="text" asp-for="Age" />
    <input type="button" value="@(Model.Age >= 20 ? "确认送出" : "禁止送出")"  disabled=@(Model.Age >= 20 ? false : true) />
</div>

本篇已同步发表至个人部落格
https://coolmandiary.blogspot.com/2021/08/net-core15mvctagheperweb.html


<<:  Day8 Swagger UI & Open Match APIs

>>:  DAY 4 Big Data 5Vs – Volume(容量) - S3+Lake Formation

云端定义 1

本系列文章同步发布於笔者网站 前言 大家好,我是 Gene,如果有参与过 Cloud Native ...

生存法则一:在快速变动的环境下生存

承认我们都有一些资讯焦虑 我们生活在快速变动的时代,无时无刻都有新的产业跟名词冒出,数据驱动决策、区...

19 首页与开始游戏按钮

先来做个首页好了 首页要有 logo 开始游戏的按钮 来把画面上面的 logo 拿掉吧吧! 预设所有...

Day 26 UserDefault

UserDefault是一种临时储存的功能,类似於我们打开游戏第一次会出现的新手教学那样,基本上他只...