.NET Core第15天_MVC的TagHeper使用_微軟Web應用框架中前端部分的演進


微軟Web應用框架中前端部分的演進

 微軟於Web應用框架中前端部分
做的三次大變革

.net Webform框架的控件(控制項)
由於高度封裝再加上各自有各自事件生命週期控管,導致能調整的彈性差,Server Side處理偏過多導致效能上也不佳。




.net MVC框架的HTML Helper
別於webform採用中度封裝,但本質仍是透過C#在進行封裝。



.net core MVC框架的 Tag Helper (標籤協助程式)
自過去前兩個框架推出由於平台侷限性,使微軟又推出一套可跨平台的框架,
當中也順勢將web應用相關框架移植進來,於MVC部分又多設計出Tag Helper語法使用上跟原生html沒有太大差異,唯獨多封裝一個asp-for來指定Model物件屬性值。
(當然之前.net mvc遺留的 html helper仍可使用。)


藉此可以觀察微軟從本來封裝程自家的風格趨向於原始html標籤風格


TahHelper預設放置於
Microsoft.AspNetCore.Mvc.TagHelpers的namespace
在一開始專案配置也會被全域性引入



BaseClass TagHelper衍生出
....


而只要在html屬性中有asp-for則代表目前使用的是TagHelper衍生的相關Helper Class
asp-for必須要與從Controller傳遞到View的ViewModel Class中Property 名稱一致

InputTagHelper原始碼

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#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)

檢視(視圖)導入,會直接把該引入的相關指令套用到所有視圖中,使我們不需要每一個View都在重複添加共用指令。

@addTagHelper
預設就會被放置並寫在ViewImport.cshtml中,若註解掉則TagHelper就無法再所有View使用。



這裡準備好StudentController的action method Index跟相應的View
沿用上次的 Student ViewModel


可以看到效果有出現從控制器傳到View的屬性資料
這裡更改一下View改為透過TagHelper方式

將@addTagHelper註解後運行效果




@removeTagHelper
就是去關閉TagHelper

通常也可以選擇在特定某一個View上去做關閉不使用TagHelper
可以去把_ViewImport.cshtml copy一份放到特定某個Controller的Folder下來做特定控制器下的TagHelper開關,該層級會覆蓋掉上一層目錄的_ViewImport.cshtml設定。


! (退出字元)
在某一個View中一部份code要用TagHelper一部份則不使用,這時可以透過!來控管。
用!可以抉擇html元素是否進用TagHelper程式。




@tagHelperPrefix

某些公司或是開發team通常都很喜歡有自定義的前綴
有點類似自己封裝某個套件或控制項感覺
通常我們在.net core mvc也可自訂前綴
在_ViewImport.cshtml可進行全域設定



這邊要注意當你有指定prefix後原先的原生tag若沒有家前綴就會失效不會跟屬性值綁定
因此會要統一都改加上有錢綴版本的tag。


在Tag屬性中使用C#程式碼

若有需要在屬性中做一些狀態切換邏輯
要注意透過Razor混和C#在前端的code要寫的位置必須在屬性的值,也就是等號右側(後面)的地方,不可以直接寫在屬性定義的地方也就是等號左側。


比方是否超過20歲的年齡判斷是否可以點送出按鈕




Student 的 Index.cshtml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
@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>






留言

這個網誌中的熱門文章

何謂淨重(Net Weight)、皮重(Tare Weight)與毛重(Gross Weight)

Architecture(架構) 和 Framework(框架) 有何不同?_軟體設計前的事前規劃的藍圖概念

經得起原始碼資安弱點掃描的程式設計習慣培養(五)_Missing HSTS Header