<a href="#sm">說明</a>
<a href="#form">Form表單</a>
<a href="#tag">使用TagBuilder建立自定義标簽</a>
<a href="#q">強類型HtmlHelper</a>
<a href="#label">LabelFor資料标簽</a>
<a href="#de">DisplayFor 和 EditorFor顯示和編輯Model資料</a>
<a href="#skt">思考題</a>
下面所有HtmlHelper代碼均寫在Views檔案夾下DefaultController檔案夾裡的DefaultAction.cshtml檔案中。這個View檔案對應一個名為DefaultController的控制器。
在HtmlHelper中生成表單Form會用到兩個函數:BeginForm和EndForm。有兩種方法可以生成<form>...</form>表單,使用方法如下所示:
我們在Form中寫入了一個TextBox和一個送出按鈕。TextBox的HtmlHelper用法上一節已經講過,而比較奇特的是送出按鈕沒有對應的HtmlHelper函數來生成,需要用HTML語言直接寫。後面我們會解決這個問題。
仔細看上面兩種生成Form方法的差別:第一種方法将Html.BeginForm()函數放入@using (){}結構中這種方法可以直接生成form的開始标記和結束标記;第二種方法先寫Html.BeginForm()函數生成開始标記,再在最後寫Html.EndForm()函數生成結尾标記。這兩種方法生成的結果是一樣的。結果如下:
從運作結果可以看出BeginForm()的第一個參數指定Action的名字,第二個參數指定Controller的名字,第三個參數指定送出的時候是用Post方法還是Get方法。上面代碼中第一個Form用的是Get方法,第二個Form用的是Post方法。
前面說到沒有送出按鈕對應的HtmlHelper函數,那麼我們就自己動手建立一個。
上帝關上了一扇門,就一定會為我們打開一扇窗。這個窗戶就是TagBuilder。顧名思義,TagBuilder就是标簽建造器,我們就用它來建造屬于我們自己标簽生成函數。
首先在項目中建立一個Classes檔案夾,用來存放我們将要建立的類。在這個檔案夾中建立一個名為HtmlExtensions.cs的類,這個類名不是強制性的,寫什麼都可以。在這個類中寫入如下代碼:
我們來解讀一下上面的代碼:
首先,要用TagBuilder就要引入System.Web.Mvc類庫。
接着我們看這個函數的參數,this HtmlHelper helper保證這個方法會被添加到HtmlHelper中,string value對應将來的送出按鈕顯示的文字,也就是value屬性。
var builder = new TagBuilder("input");使我們建立的标簽名字設為input。
MergeAttribute函數給建立出的元素添加屬性,如MergeAttribute("type", "submit") 就是加入 type="submit" 屬性。
TagRenderMode.SelfClosing使生成的标簽自我關閉,也就是說有<input />這種形式。
最後用MvcHtmlString作為傳回值是為了使傳回值不被轉義,比如"<"不會被轉成"&lt"。這是我們不想看到的。
然後我們在View中寫入下面代碼調用剛才寫好的函數:
生成結果如下:
可以看到我們在函數中所設定的标簽名、屬性、自包含都做到了。這樣我們就成功生成了自創的submit按鈕。
HtmlHelper有強類型和弱類型之分。前面所介紹的這些函數統統都是弱類型的。那麼強類型和弱類型有什麼差別?簡單點說就是強類型會用到MVC中的Model,而弱類型不用。
Htmlhelper中幾乎每一個弱類型函數都會對應一個強類型函數,它們的對應關系是強類型函數名比弱類型函數名多了一個For。比如TextBox()是一個弱類型函數,那麼其對應的強類型函數就是TextBoxFor()。
後面的部分我們需要借助Model來展示代碼,是以在解決方案中的Models檔案夾中建立一個簡單的Model,就叫Simple類。檔案名為Simple.cs代碼如下:
既然是一個簡單的Model,那我們就隻給它一個屬性:Name。
建立好這個Model之後我們就可以在Controller中給這個Model初始化并指派,并把它傳遞給View來為我們的強類型HtmlHelper做準備。編輯DefaultControllerController.cs檔案,寫入如下代碼:
圖中黃色部分初始化Model,給Model指派并将Model傳遞給View。
下面我們就在View中用強類型HtmlHelper将Model中的資料顯示出來。從上面的代碼可以看出DefaultController調用的是名為DefaultAction的View。是以我們在Views檔案夾下找到DefaultController檔案夾,編輯其中的DefaultAction.cs檔案。在檔案第一行加入如下代碼:
這行代碼表示這個View用的是Simple這個Model。
然後在檔案中插入如下代碼:
這就是我們的強類型HtmlHelper函數的一個例子TextBoxFor。這個函數隻有一個參數m =>m.Name。這裡的m可以換成其他名字,它都指代我們這裡的Model。TextBoxFor的這個參數的意思就是取Model的Name屬性。由于我們在Controller中初始化了這個值,那麼這個值應該是"Slark"。運作結果如下。
由上面結果可以看出,屬性的名字Name被指派給了這個元素的id和name,屬性值Slark指派給了value屬性。這樣我們就完成了一個簡單的強類型HtmlHelper。
強類型的一大好處是我們可以通過改動Model而改變這個Model在所有View中的顯示。如下圖的一個輸入框:

怎麼樣可以通過改動Model來改動輸入框前面的文字呢?這裡我們就要用到DataAnnotations,有人叫它中繼資料,或者叫資料批注。簡單來說它就是對資料的描述。之後用HtmlHelper的LabelFor就可以讀到這個資訊并顯示出來。我們把之前的Simple類寫成如下樣子:
代碼中黃色的部分就是我們為了使用中繼資料而增加的代碼。第一行的部分是引入了要使用中繼資料所需要的類庫。[Display(Name = "E-mail")]這一行表示當要顯示這個變量的名字的時候我們顯示"E-mail"這個字元串。HtmlHelper函數LabelFor()正是從這裡擷取到需要顯示的字元串。
在DefaultController中我們要給Email變量指派,代碼如下:
在對應的View中寫下如下代碼:
黃色标記的LabelFor函數獲得的參數是Simple類的Email屬性,LabelFor函數就會去尋找Model中對應Email的屬性的Display中繼資料,進而生成結果如下:
看生成的結果LabelFor函數會生成<Label>标簽,并且其屬性for的值對應變量名"Email",而标簽的内部文字InnerText就是Display中繼資料的Name屬性對應的值"E-mail"。
中繼資料在ASP.NET MVC的一個最主要的應用就是可以通過Model來控制資料顯示和修改時所生成的HTML元素的類型。在HtmlHelper中DisplayFor是用來顯示資料的,而EditorFor是用來編輯資料的。它們都會根據中繼資料對資料的描述生成不同類型的HTML元素。
将Simple改成如下代碼:
代碼中黃色部分是對Email資料類型的描述。它的資料類型是郵件位址EmailAddress。在View中寫下如下代碼:
DisplayFor和EditorFor都将Model的Email屬性作為自己的參數。運作結果如下:
對應的代碼如下:
從結果中可以看到由于資料類型是EmailAddress,其在顯示資料時就生成了一個發送郵件的超連結。在編輯資料時就生成了一個email專用的輸入框<input type="email">。
學而不思則罔,思而不學則殆。這裡出幾個思考題供大家檢驗學習效果。
1.HtmlHelper生成Form有幾種方法?分别怎麼寫?
2.如何自定義一個能生成<img>元素的HtmlHelper函數。
3.LableFor、DisplayFor、EditorFor函數用法有什麼異同?
本篇到此結束。HtmlHelper包含的東西比較多,還有一些東西沒有介紹,如果大家有興趣我可以繼續拓展。歡迎讨論。喜歡的話就推薦一下吧!
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。如有問題或建議,請多多賜教,非常感謝。