亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

C# 封裝HtmlHelper組件:BootstrapHelper

2020-01-24 01:01:41
字體:
來源:轉載
供稿:網友

前言:之前學習過很多的Bootstrap組件,博主就在腦海里構思:是否可以封裝一套自己Bootstrap組件庫呢。再加上看到MVC的Razor語法里面直接通過后臺方法輸出前端控件的方式,于是打算仿照HtmlHelper封裝一套BootstrapHelper,今天只是一個開頭,講述下如何封裝自己的Html組件,以后慢慢完善。

一、揭開HtmlHelper的“面紗”

經常使用Razor寫法的園友都知道,在cshtml里面,我們可以通過后臺的方法輸出成前端的html組件,比如我們隨便看兩個例子:

輸出成Html之后

博主的好奇心又來了,它是怎么做到的呢?于是將Html對象以及Label()方法轉到定義

由此可以看出Html對象是HtmlHelper類型的一個實例,而Label()方法則是HtmlHelper類型的一個擴展方法,所以就可以直接通過Html.Label()這種方式直接調用。

既然我們想要封裝自己的HtmlHelper,那么我們就必須要了解Label()方法里面是如何實現的,我們偉大的Reflector又派上用場了。我們來反編譯System.Web.MVC.dll看看。找到LabelExtensions這個類

經過一系列的轉到定義,我們找到最終的方法

同樣,我們找到TextBox()最終定義的方法

喲西,原來就是TagBuilder這個一個小東西,讓人覺得神奇得不要不要的。所以有時我們需要敢于反編譯,或許看似高級的背后其實很簡單呢~~

二、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>

再次運行

三、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());  } }}

呵呵,是不是有模有樣~~可能又有人要說博主“山寨”了,呵呵,不管山寨不山寨,你覺得爽就行。

四、總結

這篇先到這里,一路填坑,基本功能總算可用。還有一些需要完善的地方,比如泛型,比如lamada表達式等等,來日方長,博主有時間完善下。還有最基礎的一些表單控件,我們都需要封裝,這個估計還有點工作量,只能慢慢來完善了,等完善都一定的程度會開源在git上,希望自己能夠堅持下去!如果你覺得本文對你有幫助,請幫忙推薦下,您的推薦是博主堅持完善的動力。

以上所述是小編給大家介紹的C# 封裝HtmlHelper組件之BootstrapHelper ,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網網站的支持!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲国产成人精品女人久久久| 久久久99久久精品女同性| 亚洲电影在线观看| 亚洲第一天堂av| 久久久久亚洲精品成人网小说| 久久久久在线观看| 日产日韩在线亚洲欧美| 亚洲成人久久久久| 国产亚洲欧洲高清一区| 欧美日韩在线视频首页| 亚洲成年人在线| 麻豆成人在线看| 欧美国产视频一区二区| 日韩成人久久久| 国产精品色婷婷视频| 久久视频在线免费观看| 一区二区三区视频免费在线观看| 亚洲一区亚洲二区亚洲三区| 欧美在线亚洲一区| 欧美老少做受xxxx高潮| 久久99精品久久久久久青青91| 亚洲热线99精品视频| 91免费精品国偷自产在线| 国产精品精品一区二区三区午夜版| 亚洲自拍高清视频网站| 91久久精品久久国产性色也91| 国产精品视频资源| 日韩网站在线观看| 欧美小视频在线观看| 亚洲成人aaa| 国产一区二区成人| 欧美日韩中文字幕日韩欧美| 日韩av色综合| 欧美激情中文网| 激情久久av一区av二区av三区| 97香蕉超级碰碰久久免费软件| 丝袜情趣国产精品| 欧美性猛交xxxx乱大交极品| 国产精品爽爽爽爽爽爽在线观看| 亚洲人成欧美中文字幕| 亚洲视频在线观看网站| 亚洲精品视频中文字幕| 欧美精品videos另类日本| 久久久久久久久久婷婷| 91精品国产自产在线观看永久| 欧美日韩在线观看视频小说| 亚洲美女又黄又爽在线观看| 亚洲国产精品久久91精品| wwwwwwww亚洲| 久久69精品久久久久久国产越南| 成人女保姆的销魂服务| 九九热在线精品视频| 在线精品国产欧美| 狠狠爱在线视频一区| 欧美极品少妇全裸体| 另类少妇人与禽zozz0性伦| 日韩有码在线电影| 高清亚洲成在人网站天堂| 亚洲欧洲日本专区| 98午夜经典影视| 国产精品女主播视频| 成人免费看片视频| 隔壁老王国产在线精品| 欧美另类在线播放| 91久久国产婷婷一区二区| 国产一区二区激情| 国产精品嫩草视频| 欧美日韩视频在线| 久久精品99久久久久久久久| 国产一区在线播放| 欧美一区二区三区精品电影| 亚洲丝袜av一区| 精品国产一区av| 亚洲欧洲日产国码av系列天堂| 亚洲人成电影网站色xx| 一区二区三区在线播放欧美| 色婷婷综合久久久久中文字幕1| 日韩精品在线视频| 欧美亚洲国产精品| 九九九久久久久久| 欧美专区国产专区| 国产精品美女久久久久av超清| 亚洲国产成人精品久久久国产成人一区| 欧美在线视频免费观看| 久久久亚洲影院你懂的| 国产精品高清在线观看| 中文字幕在线看视频国产欧美| 日韩国产欧美精品一区二区三区| www欧美xxxx| 国产在线98福利播放视频| 超碰91人人草人人干| 欧美猛交ⅹxxx乱大交视频| 91在线视频成人| 国产精品久久久久久亚洲影视| 亚洲女人初尝黑人巨大| 一区二区日韩精品| 欧美中文字幕视频在线观看| 日韩av在线网站| 欧美性极品xxxx做受| 国产精品成人免费电影| 成人国产精品一区| 午夜精品久久久久久久久久久久| 久久久视频免费观看| 成人美女免费网站视频| 中文字幕不卡在线视频极品| 欧美日韩国产页| 亚洲欧美日韩综合| 欧美日韩性视频| 搡老女人一区二区三区视频tv| 亚洲国产天堂网精品网站| 91精品久久久久久久久不口人| 国产大片精品免费永久看nba| 久久九九亚洲综合| 日韩欧美视频一区二区三区| 精品久久久国产精品999| 91精品久久久久久久久青青| 欧美日韩第一视频| 一级做a爰片久久毛片美女图片| 亚洲风情亚aⅴ在线发布| 国产成人一区三区| 精品一区二区亚洲| 国产激情视频一区| 久久国产精品免费视频| 亚洲视频视频在线| 一区二区三区 在线观看视| 国产一区二区动漫| 青草青草久热精品视频在线网站| 中文字幕亚洲一区二区三区五十路| 国产精品一区二区三区在线播放| 视频直播国产精品| 久久久久久久久久国产精品| 精品无人区乱码1区2区3区在线| 91福利视频在线观看| 18久久久久久| 91精品国产高清久久久久久| 超碰91人人草人人干| 亚洲成人动漫在线播放| 92看片淫黄大片看国产片| 亚洲欧美日韩国产中文| 一道本无吗dⅴd在线播放一区| 两个人的视频www国产精品| 91精品中文在线| 久久在精品线影院精品国产| 久久成人国产精品| 中文字幕亚洲综合| 在线播放日韩精品| 国产男女猛烈无遮挡91| 久久成人精品电影| 亚洲日韩第一页| 日韩欧美在线视频日韩欧美在线视频| 国产亚洲成av人片在线观看桃| 日韩av有码在线| 国产成人一区二区三区| 57pao成人国产永久免费| 国产精品永久在线| 欧洲成人在线观看| 亚洲精品aⅴ中文字幕乱码| 岛国av一区二区三区| 亚洲精品第一国产综合精品| 国产精品综合网站| 国产精品美女主播在线观看纯欲| 在线观看欧美www| 黑人极品videos精品欧美裸| 国产欧美精品一区二区三区-老狼|