Asp.net MVC4高級編程學習筆記-模型學習第五課MVC表單和HTML輔助方法20171101
MVC表單和HTML輔助方法
一、表單的使用。
表單中的action與method特性。Action表示表單要提交往那裏,因此這裏就有一個URL。這個URL可以是相對或絕對地址。表單默認的method屬性值是get,如果看到表單沒有寫method屬性那就是表示method是get方式提交。另外一種就是post方式。
當使用HTTP Get請求時,瀏覽器會提取表單中元素的name特性值及相應的value特性值放到查詢字符串中。如:http://localhost?search?id=1
如果不想把值放到查詢字符串中,放到HTTP請求的主體中,就應該使用post方式。
通常情況下get方式用於讀操作(查詢),post方式用於寫操作(更新、創建、刪除)。
創建示例:
//查詢界面查詢
@using (Html.BeginForm("Search", "Home",FormMethod.Get)) { <input type="text" name="q" /> <input type="submit" value="search" /> }
//相應的控制器中的action處理Http Get得到的數據,返回查詢結果視圖
public ActionResult Search(string q) {var db = new MusicStoreDB(); var alblums = db.albums.Include("Artist") .Where(a => a.Title.Contains(q)).Take(10); ViewBag.Message = "Search"; return View(alblums); }
//視圖顯示查詢結果
@model IEnumerable<LYG.HelloWorld.Models.Album> @{ ViewBag.Title= "Search"; } <h2>Result</h2> <table> <tr> <th>Artist</th> <th>Title</th> <th>Price</th> </tr> @foreach(var item in Model) { <tr> <td>@item.Artist.Name</td> <td>@item.Title</td> <td>@string.Format("{0:c}",item.Price)</td> </tr> } </table>
二、HTML輔助方法。
1.Html.BeginForm
@using (Html.BeginForm("Search", " Home", FormMethod.Get)) { <input type="text" name="q" /> <input type="submit" name="Search" /> }
等效的html:
<form action="/Home/Search" method="get">
設置元素的class特性就要求匿名類型對象上必須有一個名為class的屬性,或者值的字典中有一個名為class的鍵。在字典中有一個“class”的鍵值不是問題,問題在於對象中帶有一個名為class的屬性。因為class是c#語言的保留關鍵字,不能用作屬性名稱或標識符,所以必須在class前面加一個@符號作為前綴:
@using (Html.BeginForm("Search", "Home", FormMethod.Get, new {target = "_blank", @class="editForm"}))
另一個問題是將屬性設置為帶有連字符的名稱(如data-val)。帶有連字符的C#屬性名是無效的,但所有的HTML輔助方法在渲染HTML時會將屬性名中的下劃線轉換為連字符。
@using (Html.BeginForm("Search", "Home", FormMethod.Get, new {target = "_blank",@class="editForm", data_validatable=true}))
等效的HTML為:
<form action="/Home/Search" class="editForm" data-validatable="true"
method="get" target="_blank">
2.Html.ValidationSummary
@Html.ValidationSummary(true)
用來顯示ModelState字典中所有驗證錯誤的無序列表。使用布爾類型參數(值為true)來告知輔助方法排除屬性級別的錯誤,而不顯示那些具體模型屬性相關的錯誤
3.Html.TextBox
@Html.TextBox("Title",Model.Title)
渲染一個type特性為text的input標簽,用於接收用戶自由形式的輸入,等效的HTML:
<input id="Title" name="Title" type="text" value="For those about to Rock We Salute You" />
4.Html.TextArea
@Html.TextArea("text","hello <br/> world")
等效HTML:
<textarea cols="80" id="text" name="text" rows="10">hello <br /> world </textarea>
5.Html.Label
@Html.LabelFor(p=>p.GenereId)
等效HTML:
<label for ="GenreId">Genre</label>
返回一個<label/>元素,並使用String類型的參數來決定渲染的文本和for特性值
6.Html.DropDownList和Html.ListBox
DropDownList允許進行單項選擇,而ListBox支持多項選擇(在要渲染的標記中,把multiple特性的值設置為multiple)
通常,select元素有兩個作用:
展示可選項的列表
展示字段的當前值
下拉列表需要包含所有可選項的SelectListItem對象集合,其中每一個SelectListItem對象又包含有Text、Value和Selected三個屬性。可以根據需要構建自己的SelectListItem對象集合,也可以使用框架中的SelectList或者MultiSelectList輔助方法類來構建。這些類可以查看任意類型的Ienumerable對象並將其轉換為SelectListItem對象的序列。
例如,StoreManager控制器中的Edit操作:
public ActionResult Edit(int id) { var album = storeDB.Albums.Single(a => a.AlbumId == id); ViewBag.Genres = new SelectList(storeDB.Genres.OrderBy(g => g.Name), "GenreId","Name",album.GenreId); return View(album); }
這裏控制器操作不僅構建了主要模型(用於編輯的模型),還構建了下拉列表輔助方法所需要的表示模型。SelectList構造函數的參數指定了原始集合(數據庫中的Genres表)、作為後臺值使用屬性名稱(Name)以及當前所選項的值(他決定將哪一項標記為選擇項)。
如果想在避免反射開銷的同時還想自己生成SelectListItem集合,可以使用LINQ的Select方法來將SelectListItem對象集放入項目Genres:
var album = MusicStoreDB.Genres .OrderBy(g => g.Name) .AsEnumerable() .Select(g => new SelectListItem { Text = g.Name, Value = g.GenreId.ToString(), Selected = album.GenreId == g.GenreId }); return View(album);
7.Html.ValidationMessage
@Html.ValidationMessage("Title")
等效HTML:
<span class="field-validation-error" data-valmsg-for="Title" data-valmsg-replace="true">
What a terrible name!
</span>
當ModelState字典中的某一特定字段出現錯誤時,可以使用ValidationMessage輔助方法來顯示相應的錯誤提示消息。
8.Html.Hidden
@Html.Hidden("WizardStep","1")
方法用於渲染隱藏的輸入元素,等效HTML:
<input id="wizardStep" name="wizardStep" type="hidden" value="1" />
強類型方法是Html.HiddenFor。如果模型有一個WizardStep屬性,就可以這樣使用:
@Html.HiddenFor(m => m.WizardStep)
9.Html.Password
@Html.Password("UserPassword")
方法用於渲染密碼字段。它除了不保留提交值,顯示密碼掩碼之外,基本與TextBox輔助方法一樣。
等效HTML:
<input id="UserPassword" name="UserPassword" type="password" value="">
Html.Password的強類型方法是Html.PasswordFor。下面的代碼展示如何使用它來顯示UserPassword屬性:
@Html.PasswordFor(m => m.UserPassword)
10.Html.RadioButton
@Html.RadioButton("color","red")
單選按鈕一般都組合一起使用,為用戶的單項選擇提供一組可選項。
等效的HTML:
<input id="color" name="color" type="radio" value="red" />
Html.RadioButton有一個強類型的對應方法Html.RadioButtonFor。強類型方法不使用名稱和值,而是用表達式來標識那些包含有要渲染屬性的對象,當用戶選擇單選按鈕時,後面會跟要提交的值:
@Html.RadioButtonFor(m => m.GenreId, "1") Rock
11.Html.CheckBox
@Html.CheckBox("IsDiscounted")
方法是唯一一個渲染兩個輸入元素的輔助方法,等效HTML:
<input id="IsDiscounted" name="IsDiscounted" type="checkbox" value="true" />
<input name="IsDiscounted" type="hidden" value="false" />
輔助方法、模型和視圖數據:
輔助方法如Html.TextBox和Html.DropDownList(以及其他所有表單輔助方法)檢查ViewData對象以獲得要顯示的當前值(在ViewBag對象中的所有值也可以通過ViewData得到)。
(1)如果想在一個表單中設置專輯的價格,可使用下面的控制器代碼
public ActionResult Edit(int id) { ViewBag.Price = 10.0; return View(); }
在相應的視圖中,使用ViewBag中的值來為TextBox輔助方法命名,可以實現渲染顯示價格的文本框:
@Html.TextBox("Price")
TextBox輔助方法將生成如下所示的HTML標記:
<input id="Price" name="Price" type="text" value="10" />
(2)當輔助方法查看ViewData裏面的內容時,他們也能看到其中的對象屬性。修改先前的控制器操作:
public ActionResult Edit(int id) { ViewBag.Album = new Album {Price = 11}; return View(); }
在響應的視圖中,可以使用下面這行代碼來顯示一個帶有專輯價格的文本框:
@Html.TextBox("Album.Price")
現在渲染出的HTML標記如下所示:
<input id="Album_Price" name="Album.Price" type="text" value="11" />
如果在ViewData中沒有匹配“Album.Price”的值,那麽輔助方法將嘗試查找與第一個點之前那部分名稱(Album)匹配的值。換言之,就是找一個Album類型的對象。然後,輔助方法估測名稱中剩余的部分(Price),並找到相應的值。
註意渲染得到的input元素的id特性值使用下劃線代替了點(但name特性依然使用點)。
(3)TextBox輔助方法依靠強類型視圖數據也能很好的工作。
public ActionResult Edit(int id) { var album = new Album {Price = 12.0m}; return View(album); }
視圖中的代碼:
@Html.TextBox("Price");
對應的HTML標記:
<input id="Price" name="Price" type="text" value="12.0" />
(4)如果想避免自動的查找數據,可向表單輔助方法提供一個顯式的值。有時,顯式提供值的方法是必須的。返回到剛才正在構建(用來編輯專輯信息)的表單。
控制器代碼:
public ActionResult Edit(int id) { var album = storeDB.Albums.Single(a => a.AlbumId == id); ViewBag.Genres = new SelectList(storeDB.Genres.OrderBy(g => g.Name) , "GenreId" , "Name" , album.GenreId); return View(album); }
視圖:
@Html.TextBox("Title", Model.Title)
強類型的輔助方法
如果不適應使用字符串字面值從視圖數據中提取值的話,也可以使用MVC提供的各種強類型輔助方法。使用強類型輔助方法時,只需要為其傳遞一個lambda表達式來指定要渲染的模型屬性。表達式的模型類型必須和為視圖指定的模型類型(使用@model指令)一致。對於專輯模型的強類型視圖,需要在視圖頂部輸入如下所示的代碼:
@model MvcMusicStore.Models.Album
一旦添加模型指令,就可以使用下面的代碼重寫前面的專輯編輯表單:
@using (Html.BeginForm()) { @Html.ValidationSummary(excludePropertyErrors: true) <fieldset> <legend>Edit Album</legend> <p> @Html.LabelFor(m => m.GenreId) @Html.DropDownListFor(m => m.GenreId, ViewBag.Genres SelectList) </p> <p> @Html.TextBoxFor(m => m.Title) @Html.ValidationMessageFor(m => m.Title) </p> <input type="submit" name="Save"> </fieldset>> }
註意:
這些強類型的輔助方法名稱除了有"For"後綴之外,跟先前使用的輔助方法還有相同的名稱。盡管該代碼生成了與先前代碼同樣的HTML標記,但是用lambda表達式代替字符串還有許多其他好處,其中包括智能感知、編譯時檢查和輕松的代碼重構。
這裏不需要顯式的為Title文本框設置值,這主要是因為lambda表達式向輔助方法提供了足夠的信息,使其能直接讀取模型的Title屬性來獲取需要的值。
模版輔助方法
ASP.NET MVC中的模版輔助方法利用元數據和模版構建HTML。其中元數據包括關於模型值(它的名稱和類型)的信息和(通過數據註解或自定義提供器添加的)模型元數據
。模型輔助方法有Html.Display和Html.Editor,以及分別與他們對應的強類型方法Html.DisplayFor和Html.EditorFor,還有它們對應的完整模型Html.DisplayForModel和Html.EditorForModel。
@Html.TextBox("Title",Model.Title)
等同於:
@Html.EditorFor(m => m.Title)
兩者生成的HTML標記是相同的,,但是EditorFor方法可以通過使用數據註解來改變生成的HTML
渲染輔助方法
12.Html.ActionLink和Html.RouteLink
ActionLink輔助方法能渲染一個超鏈接(錨標簽),渲染的鏈接指向另一個控制器操作,與前面看到的BeginForm輔助方法一樣,ActionLink輔助方法在後臺使用路由API來生成URL。
當鏈接的操作所在控制器與用來渲染當前視圖的控制器一樣時,只需要指定操作的名稱:
@Html.ActionLink("Link Text", "AnotherAction")
這裏假設采用默認路由,那麽執行這段代碼將生成如下所示的HTML標記:
<a href = "/Home/AnotherAction">LinkText</a>
當需要一個指向不同控制器操作的鏈接時,可通過ActionLink方法的第三個參數來指定控制器名稱。例如要鏈接到ShoppingCartController控制器的Index操作,可以使用下面的代碼:
@Html.ActionLink("Link Text", "Index", "ShoppingCart")
13 URL輔助方法
URL輔助方法與HTML的ActionLink和RouteLink輔助方法類似,但它不是以HTML標記的形式返回構建的URL,而是以字符串的形式返回這些URL。對此,有三個輔助方法:
Action
Content
RouteUrl
Action輔助方法與ActionLink非常類似,但是它不返回錨標簽。例如,下面的代碼會顯示瀏覽商店裏所有Jazz專輯的URL(不是鏈接):
<span> @Url.Action("Browse", "Store", new {genre = "Jazz"}, null) </span>
將會生成如下所示的HTML標記:
<span>
/Store/Browse?genre=Jazz
</span>
14 Html.Partial和Html.RenderPartial
Partial輔助方法用於將部分視圖渲染成字符串,如下將渲染一個名為AlbumDisplay的部分視圖
@Html.Partial("AlbumDisplay")
RenderPartial輔助方法與Partial非常相似,但RenderPartial不是返回字符串,而是直接寫入響應輸出流。基於這個原因,必須將RenderPartial放入代碼塊中,而不能放在代碼表達式。
@{Html.RenderPartial("AlbumDisplay"); } 或 @Html.Partial("AlbumDisplay")
一般情況下,因為Partial相對於RenderPartial來說更方便(不必使用花括號將調用封裝在代碼塊中),所以選擇Partial。然而,RenderPartial擁有較好的性能,因為它是直接寫入響應流的,但這種性能優勢需要大量的使用(高的網站流量或在循環中重復調用)才能看出來。
15 Html.Action和Html.RenderAction
Action和RenderAction之間僅有的不同之處在於:RenderAction可以直接寫入響應流。
Asp.net MVC4高級編程學習筆記-模型學習第五課MVC表單和HTML輔助方法20171101