1. 程式人生 > >Asp.net MVC4高級編程學習筆記-模型學習第五課MVC表單和HTML輔助方法20171101

Asp.net MVC4高級編程學習筆記-模型學習第五課MVC表單和HTML輔助方法20171101

流量 取值 工作 sin 輔助 一個點 大量 元數據 view

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 &lt;br /&gt; 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