C# 封裝HtmlHelper組件:BootstrapHelper。本站提示廣大學習愛好者:(C# 封裝HtmlHelper組件:BootstrapHelper)文章只能為提供參考,不一定能成為您想要的結果。以下是C# 封裝HtmlHelper組件:BootstrapHelper正文
媒介:之前進修過許多的Bootstrap組件,博主就在腦海裡構想:能否可以封裝一套本身Bootstrap組件庫呢。再加上看到MVC的Razor語法外面直接經由過程後台辦法輸入前端控件的方法,因而盤算模仿HtmlHelper封裝一套BootstrapHelper,明天只是一個開首,講述下若何封裝本身的Html組件,今後漸漸完美。
1、揭開HtmlHelper的“面紗”
常常應用Razor寫法的園友都曉得,在cshtml外面,我們可以經由過程後台的辦法輸入成前真個html組件,好比我們隨意看兩個例子:
輸入成Html以後
博主的獵奇心又來了,它是怎樣做到的呢?因而將Html對象和Label()辦法轉到界說
由此可以看出Html對象是HtmlHelper類型的一個實例,而Label()辦法則是HtmlHelper類型的一個擴大辦法,所以便可以直接經由過程Html.Label()這類方法直接挪用。
既然我們想要封裝本身的HtmlHelper,那末我們就必需要懂得Label()辦法外面是若何完成的,我們巨大的Reflector又派上用處了。我們來反編譯System.Web.MVC.dll看看。找到LabelExtensions這個類
經由一系列的轉到界說,我們找到終究的辦法
異樣,我們找到TextBox()終究界說的辦法
喲西,本來就是TagBuilder這個一個小器械,讓人認為奇異得不要不要的。所以有時我們須要勇於反編譯,也許看似高等的面前其實很簡略呢~~
2、BootstrapHelper組件封裝預備
1、界說BootstrapHelper
有了以上的基本做預備,接上去就是詳細的完成了,我們新建了一個空的MVC項目,添加以下文件。
編譯發明報錯以下
將HtmlHelper轉到界說發明它有兩個結構函數,分離有兩個、三個參數
那末,我們的BootstrapHelper也界說兩個結構函數,因而代碼釀成如許:
namespace Extensions { public class BootstrapHelper : System.Web.Mvc.HtmlHelper { /// <summary> /// 應用指定的視圖高低文和視圖數據容器來初始化 BootstrapHelper 類的新實例。 /// </summary> /// <param name="viewContext">視圖高低文</param> /// <param name="viewDataContainer">視圖數據容器</param> public BootstrapHelper(ViewContext viewContext, IViewDataContainer viewDataContainer) : base(viewContext, viewDataContainer) { } /// <summary> /// 應用指定的視圖高低文、視圖數據容器和路由聚集來初始化 BootstrapHelper 類的新實例。 /// </summary> /// <param name="viewContext">視圖高低文</param> /// <param name="viewDataContainer">視圖數據容器</param> /// <param name="routeCollection">路由聚集</param> public BootstrapHelper(ViewContext viewContext, IViewDataContainer viewDataContainer, RouteCollection routeCollection) : base(viewContext, viewDataContainer, routeCollection) { } } }
如許經由過程子類復用父類的結構函數的方法便可處理以上成績。編譯經由過程!
2、界說LabelExtensions
下面我們研討過HtmlHelper,在HtmlHelper外面,分歧的html組件界說了分歧的Extension(擴大),上面我們就以最簡略的Label標簽為例界說我們BootstrapHelper外面的Label標簽。
異樣,在Extensions文件夾外面我們新建了一個文件LabelExtensions.cs,用於界說Label標簽的擴大,它外面的根本完成以下:
namespace Extensions { public static class LabelExtensions { /// <summary> /// 經由過程應用指定的 HTML 贊助器和窗體字段的稱號,前往Label標簽 /// </summary> /// <param name="html">擴大辦法實例</param> /// <param name="id">標簽的id</param> /// <param name="content">標簽的內容</param> /// <param name="cssClass">標簽的class款式</param> /// <param name="htmlAttributes">標簽的額定屬性(假如屬性外面含有“-”,請用“_”取代)</param> /// <returns>label標簽的html字符串</returns> public static MvcHtmlString Label(this BootstrapHelper html, string id, string content, string cssClass, object htmlAttributes) { //界說標簽的稱號 TagBuilder tag = new TagBuilder("label"); //給標簽增長額定的屬性 IDictionary<string, object> attributes = BootstrapHelper.AnonymousObjectToHtmlAttributes(htmlAttributes); if (!string.IsNullOrEmpty(id)) { attributes.Add("id", id); } if (!string.IsNullOrEmpty(cssClass)) { //給標簽增長款式 tag.AddCssClass(cssClass); } //給標簽增長文本 tag.SetInnerText(content); tag.AddCssClass("control-label"); tag.MergeAttributes(attributes); return MvcHtmlString.Create(tag.ToString()); } } }
我們暫且只界說一個辦法,其他的重載我們很好擴大,這裡給一切的BootstrapHelper外面的Label標簽同一添加了“control-label”款式,固然,假如你的項目外面的label標簽界說了本身的款式,那末這裡改成你須要的款式便可。以上代碼都比擬基本,這裡就紛歧一講授。
3、界說BootstrapWebViewPage
以上界說了BootstrapHelper和LabelExtensions,預備任務是做好了,然則還少一個對象,好比我們在cshtml頁面外面@Html.Label("姓名")如許寫,Html變量是一個HtmlHelper類型的對象,那末,假如我們須要應用相似@Bootstrap.Label()這類寫法,以此類推,Bootstrap變量應當也是一個BootstrapHelper類型的對象,那末假如我們要這麼用,必需要先界說一個Bootstrap變量,這個變量究竟在哪裡界說呢。因而博主思慮,Html變量是界說在哪裡的呢?再次轉到界說
本來是在WebViewPage這個類的子類中,異樣,我們在Extensions文件夾外面也新建一個WebViewPage的子類BootstrapWebViewPage,完成代碼以下:
namespace Extensions { public abstract class BootstrapWebViewPage<T> : System.Web.Mvc.WebViewPage<T> { //在cshtml頁面外面應用的變量 public BootstrapHelper Bootstrap { get; set; } /// <summary> /// 初始化Bootstrap對象 /// </summary> public override void InitHelpers() { base.InitHelpers(); Bootstrap = new BootstrapHelper(ViewContext, this); } public override void Execute() { //throw new NotImplementedException(); } } }
至於這裡的泛型,我們今後再來做講授,這裡先不做過量糾結
4、理論
有了以上三步,一切須要的辦法和變量都齊備了,貌似曾經“萬事俱備只欠春風”了,是否是如許呢?我們來試一把
編譯,將Index.cshtml頁面封閉從新翻開,發明依然找不到Bootstrap對象
怎樣回事呢,Html是可以找到的,那Bootstrap變量去哪裡了呢。。。
經由一番查找材料,發明在View文件夾外面有一個web.config文件(之前一向沒怎樣在乎這個器械,如今想一想外面照樣有學問的哦),外面有一個節點system.web.webPages.razor上面有一個pages節點,默許是如許的:
<system.web.webPages.razor> <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <pages pageBaseType="System.Web.Mvc.WebViewPage"> <namespaces> <add namespace="System.Web.Mvc" /> <add namespace="System.Web.Mvc.Ajax" /> <add namespace="System.Web.Mvc.Html" /> <add namespace="System.Web.Routing" /> <add namespace="BootstrapHelper" /> </namespaces> </pages> </system.web.webPages.razor>
我們將pages節點的pageBaseType改成我們的WebViewPage
<system.web.webPages.razor> <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <pages pageBaseType="Extensions.BootstrapWebViewPage"> <namespaces> <add namespace="System.Web.Mvc" /> <add namespace="System.Web.Mvc.Ajax" /> <add namespace="System.Web.Mvc.Html" /> <add namespace="System.Web.Routing" /> <add namespace="BootstrapHelper" /> </namespaces> </pages> </system.web.webPages.razor>
然後編譯,從新翻開Index.cshtml。
OK,可以找到Bootstrap對象了。我們將Index.cshtml外面寫入以下內容:
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> </head> <body> <div> @Html.Label("姓名") @Html.TextBox("a", "Jim") @Bootstrap.Label(null, "Bootstrap Label標簽", null, null) </div> </body> </html>
運轉看看後果:
怎樣照樣報錯呢?這個成績應當不難懂得,由於在razor外面應用@挪用後台變量和辦法的時刻也存在定名空間的概念,這個定名空間在哪裡援用呢,照樣在View文件夾外面的web.config外面,在system.web.webPages.razor節點上面存在namespace的節點,我們將自界說的Label()擴大辦法地點的定名空間加出來便可。因而設置裝備擺設釀成如許:
<system.web.webPages.razor> <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <pages pageBaseType="Extensions.BootstrapWebViewPage"> <namespaces> <add namespace="System.Web.Mvc" /> <add namespace="System.Web.Mvc.Ajax" /> <add namespace="System.Web.Mvc.Html" /> <add namespace="System.Web.Routing" /> <add namespace="BootstrapHelper" /> <add namespace="Extensions"/> </namespaces> </pages> </system.web.webPages.razor>
再次運轉
3、BootstrapHelper組件完美
經由過程下面一系列發明坑、填坑的閱歷,一個最最簡略的BootstrapHelper組件曾經根本可用。我們將LabelExtensions簡略完美下:
namespace Extensions { public static class LabelExtensions { public static MvcHtmlString Label(this BootstrapHelper html, string id) { return Label(html, id, null, null, null); } public static MvcHtmlString Label(this BootstrapHelper html, string content) { return Label(html, null, content, null, null); } public static MvcHtmlString Label(this BootstrapHelper html, string id, string content) { return Label(html, id, content, null, null); } public static MvcHtmlString Label(this BootstrapHelper html, string id, string content, object htmlAttributes) { return Label(html, id, content, null, htmlAttributes); } /// <summary> /// 經由過程應用指定的 HTML 贊助器和窗體字段的稱號,前往Label標簽 /// </summary> /// <param name="html">擴大辦法實例</param> /// <param name="id">標簽的id</param> /// <param name="content">標簽的內容</param> /// <param name="cssClass">標簽的class款式</param> /// <param name="htmlAttributes">標簽的額定屬性(假如屬性外面含有“-”,請用“_”取代)</param> /// <returns>label標簽的html字符串</returns> public static MvcHtmlString Label(this BootstrapHelper html, string id, string content, string cssClass, object htmlAttributes) { //界說標簽的稱號 TagBuilder tag = new TagBuilder("label"); //給標簽增長額定的屬性 IDictionary<string, object> attributes = BootstrapHelper.AnonymousObjectToHtmlAttributes(htmlAttributes); if (!string.IsNullOrEmpty(id)) { attributes.Add("id", id); } if (!string.IsNullOrEmpty(cssClass)) { //給標簽增長款式 tag.AddCssClass(cssClass); } //給標簽增長文本 tag.SetInnerText(content); tag.AddCssClass("control-label"); tag.MergeAttributes(attributes); return MvcHtmlString.Create(tag.ToString()); } } }
呵呵,是否是有模有樣~~能夠又有人要說博主“盜窟”了,呵呵,不論盜窟不盜窟,你認為爽就行。
4、總結
這篇先到這裡,一路填坑,根本功效總算可用。還有一些須要完美的處所,好比泛型,好比lamada表達式等等,明天將來方長,博主有時光完美下。還有最基本的一些表單控件,我們都須要封裝,這個估量還有點任務量,只能漸漸來完美了,等完美都必定的水平會開源在git上,願望本身可以或許保持下去!假如你認為本文對你有贊助,請協助推舉下,您的推舉是博主保持完美的動力。
以上所述是小編給年夜家引見的C# 封裝HtmlHelper組件之BootstrapHelper ,願望對年夜家有所贊助,假如年夜家有任何疑問請給我留言,小編會實時答復年夜家的。在此也異常感激年夜家對網站的支撐!