欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C# 封裝HtmlHelper組件:BootstrapHelper

 更新時(shí)間:2016年08月04日 14:12:34   投稿:mrr  
這篇文章主要介紹了C# 封裝HtmlHelper組件之BootstrapHelper 的相關(guān)資料,需要的朋友可以參考下

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

一、揭開HtmlHelper的“面紗”

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

輸出成Html之后

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

由此可以看出Html對(duì)象是HtmlHelper類型的一個(gè)實(shí)例,而Label()方法則是HtmlHelper類型的一個(gè)擴(kuò)展方法,所以就可以直接通過Html.Label()這種方式直接調(diào)用。

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

經(jīng)過一系列的轉(zhuǎn)到定義,我們找到最終的方法

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

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

二、BootstrapHelper組件封裝準(zhǔn)備

1、定義BootstrapHelper

有了以上的基礎(chǔ)做準(zhǔn)備,接下來就是具體的實(shí)現(xiàn)了,我們新建了一個(gè)空的MVC項(xiàng)目,添加如下文件。

編譯發(fā)現(xiàn)報(bào)錯(cuò)如下

將HtmlHelper轉(zhuǎn)到定義發(fā)現(xiàn)它有兩個(gè)構(gòu)造函數(shù),分別有兩個(gè)、三個(gè)參數(shù)

那么,我們的BootstrapHelper也定義兩個(gè)構(gòu)造函數(shù),于是代碼變成這樣:

namespace Extensions
{
 public class BootstrapHelper : System.Web.Mvc.HtmlHelper
 {
  /// <summary>
  /// 使用指定的視圖上下文和視圖數(shù)據(jù)容器來初始化 BootstrapHelper 類的新實(shí)例。
  /// </summary>
  /// <param name="viewContext">視圖上下文</param>
  /// <param name="viewDataContainer">視圖數(shù)據(jù)容器</param>
  public BootstrapHelper(ViewContext viewContext, IViewDataContainer viewDataContainer)
   : base(viewContext, viewDataContainer)
  { }
  /// <summary>
  /// 使用指定的視圖上下文、視圖數(shù)據(jù)容器和路由集合來初始化 BootstrapHelper 類的新實(shí)例。
  /// </summary>
  /// <param name="viewContext">視圖上下文</param>
  /// <param name="viewDataContainer">視圖數(shù)據(jù)容器</param>
  /// <param name="routeCollection">路由集合</param>
  public BootstrapHelper(ViewContext viewContext, IViewDataContainer viewDataContainer, RouteCollection routeCollection)
   : base(viewContext, viewDataContainer, routeCollection)
  { }
 }
}

這樣通過子類復(fù)用父類的構(gòu)造函數(shù)的方式即可解決以上問題。編譯通過!

2、定義LabelExtensions

上面我們研究過HtmlHelper,在HtmlHelper里面,不同的html組件定義了不同的Extension(擴(kuò)展),下面我們就以最簡(jiǎn)單的Label標(biāo)簽為例定義我們BootstrapHelper里面的Label標(biāo)簽。

同樣,在Extensions文件夾里面我們新建了一個(gè)文件LabelExtensions.cs,用于定義Label標(biāo)簽的擴(kuò)展,它里面的基本實(shí)現(xiàn)如下:

namespace Extensions
{
 public static class LabelExtensions
 {
  /// <summary>
  /// 通過使用指定的 HTML 幫助器和窗體字段的名稱,返回Label標(biāo)簽
  /// </summary>
  /// <param name="html">擴(kuò)展方法實(shí)例</param>
  /// <param name="id">標(biāo)簽的id</param>
  /// <param name="content">標(biāo)簽的內(nèi)容</param>
  /// <param name="cssClass">標(biāo)簽的class樣式</param>
  /// <param name="htmlAttributes">標(biāo)簽的額外屬性(如果屬性里面含有“-”,請(qǐng)用“_”代替)</param>
  /// <returns>label標(biāo)簽的html字符串</returns>
  public static MvcHtmlString Label(this BootstrapHelper html, string id, string content, string cssClass, object htmlAttributes)
  {
   //定義標(biāo)簽的名稱
   TagBuilder tag = new TagBuilder("label");
   //給標(biāo)簽增加額外的屬性
   IDictionary<string, object> attributes = BootstrapHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
   if (!string.IsNullOrEmpty(id))
   {
    attributes.Add("id", id);
   }
   if (!string.IsNullOrEmpty(cssClass))
   {
    //給標(biāo)簽增加樣式
    tag.AddCssClass(cssClass);
   }
   //給標(biāo)簽增加文本
   tag.SetInnerText(content);
   tag.AddCssClass("control-label");
   tag.MergeAttributes(attributes);
   return MvcHtmlString.Create(tag.ToString());
  }
 }
}

我們暫且只定義一個(gè)方法,其他的重載我們很好擴(kuò)展,這里給所有的BootstrapHelper里面的Label標(biāo)簽統(tǒng)一添加了“control-label”樣式,當(dāng)然,如果你的項(xiàng)目里面的label標(biāo)簽定義了自己的樣式,那么這里改成你需要的樣式即可。以上代碼都比較基礎(chǔ),這里就不一一講解。

3、定義BootstrapWebViewPage

以上定義了BootstrapHelper和LabelExtensions,準(zhǔn)備工作是做好了,但是還少一個(gè)對(duì)象,比如我們?cè)赾shtml頁面里面@Html.Label("姓名")這樣寫,Html變量是一個(gè)HtmlHelper類型的對(duì)象,那么,如果我們需要使用類似@Bootstrap.Label()這種寫法,以此類推,Bootstrap變量應(yīng)該也是一個(gè)BootstrapHelper類型的對(duì)象,那么如果我們要這么用,必須要先定義一個(gè)Bootstrap變量,這個(gè)變量到底在哪里定義呢。于是博主思考,Html變量是定義在哪里的呢?再次轉(zhuǎn)到定義

原來是在WebViewPage這個(gè)類的子類中,同樣,我們?cè)贓xtensions文件夾里面也新建一個(gè)WebViewPage的子類BootstrapWebViewPage,實(shí)現(xiàn)代碼如下:

namespace Extensions
{
 public abstract class BootstrapWebViewPage<T> : System.Web.Mvc.WebViewPage<T>
 {
  //在cshtml頁面里面使用的變量
  public BootstrapHelper Bootstrap { get; set; }
  /// <summary>
  /// 初始化Bootstrap對(duì)象
  /// </summary>
  public override void InitHelpers()
  {
   base.InitHelpers();
   Bootstrap = new BootstrapHelper(ViewContext, this);
  }
  public override void Execute()
  {
   //throw new NotImplementedException();
  }
 }
}

至于這里的泛型,我們以后再來做講解,這里先不做過多糾結(jié)

4、實(shí)踐

有了以上三步,所有需要的方法和變量都齊全了,貌似已經(jīng)“萬事俱備只欠東風(fēng)”了,是不是這樣呢?我們來試一把

編譯,將Index.cshtml頁面關(guān)閉重新打開,發(fā)現(xiàn)仍然找不到Bootstrap對(duì)象

怎么回事呢,Html是可以找到的,那Bootstrap變量去哪里了呢。。。

經(jīng)過一番查找資料,發(fā)現(xiàn)在View文件夾里面有一個(gè)web.config文件(之前一直沒怎么在意這個(gè)東西,現(xiàn)在想想里面還是有學(xué)問的哦),里面有一個(gè)節(jié)點(diǎn)system.web.webPages.razor下面有一個(gè)pages節(jié)點(diǎn),默認(rèn)是這樣的:

<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節(jié)點(diǎn)的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對(duì)象了。我們將Index.cshtml里面寫入如下內(nèi)容:

@{
 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標(biāo)簽", null, null)
 </div>
</body>
</html>

運(yùn)行看看效果:

怎么還是報(bào)錯(cuò)呢?這個(gè)問題應(yīng)該不難理解,因?yàn)樵趓azor里面使用@調(diào)用后臺(tái)變量和方法的時(shí)候也存在命名空間的概念,這個(gè)命名空間在哪里引用呢,還是在View文件夾里面的web.config里面,在system.web.webPages.razor節(jié)點(diǎn)下面存在namespace的節(jié)點(diǎn),我們將自定義的Label()擴(kuò)展方法所在的命名空間加進(jìn)去即可。于是配置變成這樣:

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

再次運(yùn)行

三、BootstrapHelper組件完善

通過上面一系列發(fā)現(xiàn)坑、填坑的經(jīng)歷,一個(gè)最最簡(jiǎn)單的BootstrapHelper組件已經(jīng)基本可用。我們將LabelExtensions簡(jiǎn)單完善下:

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標(biāo)簽
  /// </summary>
  /// <param name="html">擴(kuò)展方法實(shí)例</param>
  /// <param name="id">標(biāo)簽的id</param>
  /// <param name="content">標(biāo)簽的內(nèi)容</param>
  /// <param name="cssClass">標(biāo)簽的class樣式</param>
  /// <param name="htmlAttributes">標(biāo)簽的額外屬性(如果屬性里面含有“-”,請(qǐng)用“_”代替)</param>
  /// <returns>label標(biāo)簽的html字符串</returns>
  public static MvcHtmlString Label(this BootstrapHelper html, string id, string content, string cssClass, object htmlAttributes)
  {
   //定義標(biāo)簽的名稱
   TagBuilder tag = new TagBuilder("label");
   //給標(biāo)簽增加額外的屬性
   IDictionary<string, object> attributes = BootstrapHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
   if (!string.IsNullOrEmpty(id))
   {
    attributes.Add("id", id);
   }
   if (!string.IsNullOrEmpty(cssClass))
   {
    //給標(biāo)簽增加樣式
    tag.AddCssClass(cssClass);
   }
   //給標(biāo)簽增加文本
   tag.SetInnerText(content);
   tag.AddCssClass("control-label");
   tag.MergeAttributes(attributes);
   return MvcHtmlString.Create(tag.ToString());
  }
 }
}

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

四、總結(jié)

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

以上所述是小編給大家介紹的C# 封裝HtmlHelper組件之BootstrapHelper ,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

最新評(píng)論