轉:1.ASP.Net MVC開發基礎學習筆記;2.HtmlHelper與擴展方法

1、一個功能強大的頁面開發輔助類—HtmlHelper初步瞭解

1.1 有失必有得

  在ASP.Net MVC中微軟並無提供相似服務器端控件那種開發方式,畢竟微軟的MVC就是傳統的請求處理響應的迴歸。因此拋棄以前的那種事件響應的模型,拋棄服務器端控件也理所固然。html

  可是,若是手寫Html標籤效率又比較低,可重用度比較低。這時,咱們該怎樣來提升效率呢?首先,通過上篇咱們知道能夠經過ViewData傳遞數據,因而咱們能夠寫出如下的Html代碼:web

<input name="UserName" type="text" value="<%: ViewData["UserName"] %>" />

  雖然以上代碼能夠解決問題,可是效率仍是比較低,特別是在列表集合項較多的時候,工做量會比較大。那麼,還有木有一種更好的方式呢?別急,微軟已經爲咱們想好了策略。微軟爲開發人員快速開發前臺頁面提供了豐富的HtmlHelper的輔助類,輔助咱們快速開發前臺頁面,也提供了可擴展的接口,前臺頁面的標籤能夠能夠作到高度可重用編程

1.2 HtmlHelper初窺

  咱們能夠經過在頁面中經過Html.XXX來實現快速的Html標籤編輯,而且能夠方便地進行數據綁定。服務器

<%: Html.Raw("<p>Hello,I am HtmlHelper!</p>") %>

  那麼,爲何能夠在頁面中調用Html.XXX方法呢?經過ILSpy反編譯ViewPage頁,咱們能夠看到原來在ViewPage下有一個HtmlHelper類型的屬性-Html。(這下終於知道,爲何能夠在頁面中使用Html.xxxx()了)mvc

  那麼這個HtmlHelper類又是一個什麼類型的大神呢?繼續反編譯查看,在System.Web.Mvc命名空間下的HtmlHelper類型以下圖所示,通過MSDN大神的講解,HtmlHelper支持在視圖中呈現 HTML 控件。那咱們看看在此類中有木有傳說中的TextBox、CheckBox的方法呢?經查看,木有。ui

  那麼,咱們爲何能夠在頁面中使用Html.TextBox()方法呢?這裏就涉及到一個叫作「擴展方法」的東東了,HtmlHelper 類的擴展方法在 System.Web.Mvc.Html 命名空間中。 這些擴展添加了用於建立窗體、呈現 HTML 控件、呈現分部視圖、執行輸入驗證等功能的幫助器方法。那麼,有關如何自定義擴展方法請參閱本文第三部分,這裏先賣個關子,暫不介紹。this

1.3 爲何使用HtmlHelper?

   思考這樣一個場景:咱們的項目第一個版本中的路由規則是這樣的{controller}/{action}/{id},因而咱們項目中全部的<a>標籤所指向的都是以剛剛的規則命名的href(例如:<a href='Home/User/1'></a>)。可是在第二版中,咱們的路由規則也會變成了{controller}-{action}-{id},那麼咱們剛剛爲超連接所設置的href便都沒法正常訪問了。這時,咱們須要進行替換,單個替換或批量替換(例如改成:<a href='Home-User-1'></a>),雖然也能夠解決問題,可是無疑增長了工做量,效率很低。編碼

  那麼,怎樣來屏蔽這種變化所帶來的不便呢?這裏,經過使用HtmlHelper爲咱們提供的ActionLink標籤,即可以解決這個問題。由於HtmlHelper是從服務器端自動幫你生成a標籤,所以所生成的href會遵循目前的路由規則,也就幫咱們屏蔽了變化,提升了工做效率。spa

2、沒有服務器控件也能幹大事—HtmlHelper重要方法介紹

  PS:這裏的實例均沒有加<% %>或@符號,要運行請自行加上。3d

  (1)ActionLink與RouteLink

複製代碼
Html.ActionLink("這是一個鏈接", "Index", "Home")
帶有QueryString的寫法
Html.ActionLink("這是一個鏈接", "Index", "Home", new { page=1 },null)
Html.ActionLink("這是一個鏈接", "Index", new { page=1 })
有其它Html屬性的寫法
Html.ActionLink("這是一個鏈接", "Index", "Home", new { id="link1" })
Html.ActionLink("這是一個鏈接", "Index",null, new { id="link1" })
QueryString與Html屬性同時存在
Html.ActionLink("這是一個鏈接", "Index", "Home", new { page = 1 }, new { id = "link1" })
Html.ActionLink("這是一個鏈接", "Index" , new { page = 1 }, new { id = "link1" })
複製代碼

  其生成的結果爲:

複製代碼
<a href="/">這是一個鏈接</a>
帶有QueryString的寫法
<a href="/?page=1">這是一個鏈接</a>
<a href="/?page=1">這是一個鏈接</a>
有其它Html屬性的寫法
<a href="/?Length=4" id="link1">這是一個鏈接</a>
<a href="/" id="link1">這是一個鏈接</a>
QueryString與Html屬性同時存在
<a href="/?page=1" id="link1">這是一個鏈接</a>
<a href="/?page=1" id="link1">這是一個鏈接</a>
複製代碼

  RouteLink在用法幾乎與ActionLink一致,這裏就再也不介紹,詳情請參與MSDN;

  (2)TextBox與TextArea

  ①TextBox

Html.TextBox("input1") 
Html.TextBox("input2",Model.CategoryName,new{ @style = "width:300px;" }) 
Html.TextBox("input3", ViewData["Name"],new{ @style = "width:300px;" }) 
Html.TextBoxFor(a => a.CategoryName, new { @style = "width:300px;" })

  其生成的結果爲:

<input id="input1" name="input1" type="text" value="" />
<input id="input2" name="input2" style="width:300px;" type="text" value="Beverages" />
<input id="input3" name="input3" style="width:300px;" type="text" value="" />
<input id="CategoryName" name="CategoryName" style="width:300px;" type="text" value="Electronic" />

  ②TextArea

Html.TextArea("input5", Model.CategoryName, 3, 9,null)
Html.TextAreaFor(a => a.CategoryName, 3, 3, null)

  其生成的結果爲:

<textarea cols="9" id="input5" name="input5" rows="3">Electronic</textarea>
<textarea cols="3" id="CategoryName" name="CategoryName" rows="3">Electronic</textarea>

  這裏能夠看到,咱們可使用強類型來生成Html標籤,例如:Html.TextBoxFor(a => a.CategoryName, new { @style = "width:300px;" }),這裏的CategoryName就是某個類型的屬性。

  (3)CheckBox

Html.CheckBox("chk1",true) 
Html.CheckBox("chk1", new { @class="checkBox"}) 
Html.CheckBoxFor(a =>a.IsVaild, new { @class = "checkBox" })

   其生成的結果爲:

<input checked="checked" id="chk1" name="chk1" type="checkbox" value="true" /><input name="chk1" type="hidden" value="false" />
<input class="checkBox" id="chk1" name="chk1" type="checkbox" value="true" /><input name="chk1" type="hidden" value="false" />
<input checked="checked" class="checkBox" id="IsVaild" name="IsVaild" type="checkbox" value="true" /><input name="IsVaild" type="hidden" value="false" />

  (4)DropDownList

Html.DropDownList("ddl1", (SelectList)ViewData["Categories"],  "--Select One--")
Html.DropDownListFor(a => a.CategoryName, (SelectList)ViewData["Categories"], "--Select One--", new { @class = "dropdownlist" })

  其生成的結果爲:

複製代碼
<select id="ddl1" name="ddl1">
<option value="">--Select One--</option>
<option value="1">Beverages</option>
<option value="2">Condiments</option>
<option selected="selected" value="3">Confections</option>
<option value="4">Dairy Products</option>
<option value="5">Grains/Cereals</option>
<option value="6">Meat/Poultry</option>
<option value="7">Produce</option>
<option value="8">Seafood</option>
</select>
<select class="dropdownlist" id="CategoryName" name="CategoryName">
<option value="">--Select One--</option>
<option value="1">Beverages</option>
<option value="2">Condiments</option>
<option value="3">Confections</option>
<option value="4">Dairy Products</option>
<option value="5">Grains/Cereals</option>
<option value="6">Meat/Poultry</option>
<option value="7">Produce</option>
<option value="8">Seafood</option>
</select>
複製代碼

  (5)RadioButton

男<%: Html.RadioButton("Gender","1",true) %>
女<%: Html.RadioButton("Gender","2",false) %>

  其生成的代碼爲:

男<input checked="checked" id="Gender" name="Gender" type="radio" value="1" />
女<input id="Gender" name="Gender" type="radio" value="2" />

  (6)Encode與Raw

  Encode會將內容進行編碼話,所以,若是你的內容中含有Html標籤的話那麼會被解析成特殊字符,例如:

<%: Html.Encode("<p>哈哈</p>") %>

  其生成的代碼爲:

&amp;lt;p&amp;gt;哈哈&amp;lt;/p&amp;gt;

  這裏主要是爲了防止XSS攻擊和惡意腳本,所以在MVC中,默認的<%: %>就實現了<%: Html.Encode() %>。可是,某些時候若是咱們須要輸出Html或JavaScript內容的字符串,這時咱們可使用HtmlHelper爲咱們提供的其餘方法。例如咱們要輸出剛剛那句話,咱們能夠以下使用:

<%: Html.Raw("<p>哈哈</p>") %>

  其生成的代碼爲:

<p>哈哈</p>

  在HtmlHelper中還提供了許多的擴展方法供咱們方便建立Html,好比:BeginForm、EndForm等。關於其餘的方法介紹,請自行搜索,這裏再也不一一贅述。

3、隨時隨地我也能擴展—HtmlHelper擴展方法簡介

3.1 擴展方法簡介

  藉助MSDN的介紹:「擴展方法使你可以向現有類型「添加」方法,而無需建立新的派生類型、從新編譯或以其餘方式修改原始類型。」擴展方法是一種特殊的靜態方法,但能夠像擴展類型上的實例方法同樣進行調用。咱們能夠回到第一部分對HtmlHelper的擴展類-InputExtension類上,它是對於HtmlHelper的擴展,那麼怎麼鑑別它是HtmlHelper的擴展呢?

3.2 擴展方法的三要素

  (1)靜態類

  能夠從上圖看出,InputExtension首先是一個靜態類;

  (2)靜態方法

  既然是靜態類,那麼其全部的方法必然都是靜態方法,例如:public static MvcHtmlString CheckBox();

  (3)this關鍵字

  能夠從方法名定義中看出,第一個參數都是this HtmlHelper htmlHelper,表明對HtmlHelper類的擴展;

3.3 自定義擴展方法

  (1)在Models文件夾下新建一個類,取名爲:MyHtmlHelperExt

  (2)將MyHtmlHelperExt設置爲static,並寫入如下的一個靜態方法:

public static HtmlString MyExtHtmlLabel(this HtmlHelper helper, string value)
{
      return new HtmlString(string.Format("<span style='font-weight:bold;'>Hello-{0}-End</span>", value));
}

  (3)肯定知足了擴展方法的三要素以後,將命名空間改成:System.Web.Mvc。

namespace System.Web.Mvc

PS:爲何要改命名空間爲System.Web.Mvc?

這是由於若是不改命名空間,咱們要使用自定義的擴展方法須要在每一個頁面中引入Models(MyHtmlHelper所在的那個命名空間)這個命名空間,爲了防止重複的命名空間引入操做(想一想咱們使用Html.TextBox()不也沒有引入命名空間麼?),因而咱們將命名空間與HtmlHelper類所在的命名空間保持一致。

  (4)在頁面中咱們就可使用咱們本身寫的擴展方法了

<%: Html.MyExtHtmlLabel("EdisonChou") %>

  (5)查看頁面效果

參考文章

(1)馬倫,《ASP.Net MVC視頻教程》,http://bbs.itcast.cn/thread-26722-1-1.html

(2)oer,《HtmlHelper使用大全》,http://www.cnblogs.com/oer2001/archive/2013/03/19/2968475.html

(3)MSDN,《擴展方法(C#編程指南)》,http://technet.microsoft.com/zh-cn/bb383977

(4)MSDN,《HtmlHelper類(System.Web.Mvc)》,http://msdn.microsoft.com/zh-cn/library/system.web.mvc.htmlhelper(v=vs.108).aspx

 

相關文章
相關標籤/搜索