HtmlHelper用法大全(下)

目錄:

說明

本節接續上一節MVC5 + EF6 + Bootstrap3 (8) HtmlHelper用法大全(上),繼續討論HtmlHelper的用法。

下面所有HtmlHelper代碼均寫在Views文件夾下DefaultController文件夾裏的DefaultAction.cshtml文件中。這個View文件對應一個名爲DefaultController的控制器。

Form表單

在HtmlHelper中生成表單Form會用到兩個函數:BeginForm和EndForm。有兩種方法可以生成<form>...</form>表單,使用方法如下所示:

複製代碼
@using (Html.BeginForm("actionName", "controllerName", FormMethod.Get))
{
    @Html.TextBox("NameId")
    <input type="submit" value="SubmitButton" />
}

@{Html.BeginForm("actionName", "controllerName", FormMethod.Post);}
    @Html.TextBox("NameId")
    <input type="submit" value="SubmitButton" />
@{Html.EndForm();}
複製代碼

我們在Form中寫入了一個TextBox和一個提交按鈕。TextBox的HtmlHelper用法上一節已經講過,而比較奇特的是提交按鈕沒有對應的HtmlHelper函數來生成,需要用HTML語言直接寫。後面我們會解決這個問題。

仔細看上面兩種生成Form方法的區別:第一種方法將Html.BeginForm()函數放入@using (){}結構中這種方法可以直接生成form的開始標記和結束標記;第二種方法先寫Html.BeginForm()函數生成開始標記,再在最後寫Html.EndForm()函數生成結尾標記。這兩種方法生成的結果是一樣的。結果如下:

複製代碼
<form action="/controllerName/actionName" method="get">
  <
input id="NameId" name="NameId" type="text" value="" />
<input type="submit" value="SubmitButton" /> </form>
<form action="/controllerName/actionName" method="post">   <input id="NameId" name="NameId" type="text" value="" />   <input type="submit" value="SubmitButton" /> </form>
複製代碼

從運行結果可以看出BeginForm()的第一個參數指定Action的名字,第二個參數指定Controller的名字,第三個參數指定提交的時候是用Post方法還是Get方法。上面代碼中第一個Form用的是Get方法,第二個Form用的是Post方法。

使用TagBuilder創建自定義標籤

前面說到沒有提交按鈕對應的HtmlHelper函數,那麼我們就自己動手創建一個。

上帝關上了一扇門,就一定會爲我們打開一扇窗。這個窗戶就是TagBuilder。顧名思義,TagBuilder就是標籤建造器,我們就用它來建造屬於我們自己標籤生成函數。

首先在項目中創建一個Classes文件夾,用來存放我們將要創建的類。在這個文件夾中創建一個名爲HtmlExtensions.cs的類,這個類名不是強制性的,寫什麼都可以。在這個類中寫入如下代碼:

複製代碼
using System.Web.Mvc;
public static class HtmlExtensions
{
    /// <summary>
    /// 自定義一個@html.Submit()
    /// </summary>
    /// <param name="helper"></param>
    /// <param name="value">value屬性</param>
    /// <returns></returns>
    public static MvcHtmlString Submit(this HtmlHelper helper, string value)
    {
        var builder = new TagBuilder("input");
        builder.MergeAttribute("type", "submit");
        builder.MergeAttribute("value", value);        
        return MvcHtmlString.Create(builder.ToString(TagRenderMode.SelfClosing)); 
  }
}
複製代碼

我們來解讀一下上面的代碼:

  • 首先,要用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中寫入下面代碼調用剛纔寫好的函數:

@Html.Submit("SubmitButton")

生成結果如下:

<input type="submit" value="SubmitButton" />

可以看到我們在函數中所設置的標籤名、屬性、自包含都做到了。這樣我們就成功生成了自創的submit按鈕。

強類型HtmlHelper

HtmlHelper有強類型和弱類型之分。前面所介紹的這些函數統統都是弱類型的。那麼強類型和弱類型有什麼區別?簡單點說就是強類型會用到MVC中的Model,而弱類型不用。

Htmlhelper中幾乎每一個弱類型函數都會對應一個強類型函數,它們的對應關係是強類型函數名比弱類型函數名多了一個For。比如TextBox()是一個弱類型函數,那麼其對應的強類型函數就是TextBoxFor()。

後面的部分我們需要藉助Model來展示代碼,因此在解決方案中的Models文件夾中創建一個簡單的Model,就叫Simple類。文件名爲Simple.cs代碼如下:

複製代碼
namespace SlarkInc.Models
{
    public class Simple
    {
        public string Name{ get; set; }
    }
}
複製代碼

既然是一個簡單的Model,那我們就只給它一個屬性:Name。

創建好這個Model之後我們就可以在Controller中給這個Model初始化並賦值,並把它傳遞給View來爲我們的強類型HtmlHelper做準備。編輯DefaultControllerController.cs文件,寫入如下代碼:

複製代碼
using System.Web.Mvc;
using SlarkInc.Models;

namespace SlarkInc.Controllers
{
    public class DefaultControllerController : Controller
    {
        // GET: /DefaultController/
        public ActionResult DefaultAction()
        {
            Simple s = new Simple();
            s.Name= "Slark";
            return View(s);
        }
    }
}
複製代碼

圖中黃色部分初始化Model,給Model賦值並將Model傳遞給View。

下面我們就在View中用強類型HtmlHelper將Model中的數據顯示出來。從上面的代碼可以看出DefaultController調用的是名爲DefaultAction的View。因此我們在Views文件夾下找到DefaultController文件夾,編輯其中的DefaultAction.cshtml文件。在文件第一行加入如下代碼:

@model SlarkInc.Models.Simple

這行代碼表示這個View用的是Simple這個Model。

然後在文件中插入如下代碼:

@Html.TextBoxFor(m =>m.Name)

這就是我們的強類型HtmlHelper函數的一個例子TextBoxFor。這個函數只有一個參數m =>m.Name。這裏的m可以換成其他名字,它都指代我們這裏的Model。TextBoxFor的這個參數的意思就是取Model的Name屬性。由於我們在Controller中初始化了這個值,那麼這個值應該是"Slark"。運行結果如下。

<input id="Name" name="Name" type="text" value="Slark" />

由上面結果可以看出,屬性的名字Name被賦值給了這個元素的id和name,屬性值Slark賦值給了value屬性。這樣我們就完成了一個簡單的強類型HtmlHelper。

LabelFor數據標籤

強類型的一大好處是我們可以通過改動Model而改變這個Model在所有View中的顯示。如下圖的一個輸入框:

怎麼樣可以通過改動Model來改動輸入框前面的文字呢?這裏我們就要用到DataAnnotations,有人叫它元數據,或者叫數據批註。簡單來說它就是對數據的描述。之後用HtmlHelper的LabelFor就可以讀到這個信息並顯示出來。我們把之前的Simple類寫成如下樣子:

複製代碼
using System.ComponentModel.DataAnnotations;
namespace SlarkInc.Models
{    
    public class Simple
    {
        [Display(Name = "Name")]
public string Name { get; set; } [Display(Name = "E-mail")]
    
public string Email { get; set; } } }
複製代碼

代碼中黃色的部分就是我們爲了使用元數據而增加的代碼。第一行的部分是引入了要使用元數據所需要的類庫。[Display(Name = "E-mail")]這一行表示當要顯示這個變量的名字的時候我們顯示"E-mail"這個字符串。HtmlHelper函數LabelFor()正是從這裏獲取到需要顯示的字符串。

在DefaultController中我們要給Email變量賦值,代碼如下:

複製代碼
using System.Web.Mvc;
using SlarkInc.Models;

namespace SlarkInc.Controllers
{
    public class DefaultControllerController : Controller
    {
        // GET: /DefaultController/
        public ActionResult DefaultAction()
        {
            Simple s = new Simple();
            s.Name = "Slark";
            s.Email = "[email protected]";
            return View(s);
        }
    }
}
複製代碼

在對應的View中寫下如下代碼:

@Html.LabelFor(m => m.Email)
: @Html.TextBoxFor(m => m.Email)

黃色標記的LabelFor函數獲得的參數是Simple類的Email屬性,LabelFor函數就會去尋找Model中對應Email的屬性的Display元數據,進而生成結果如下:

<label for="Email">E-mail</label>
: <input id="Email" name="Email" type="text" value="[email protected]" />

看生成的結果LabelFor函數會生成<Label>標籤,並且其屬性for的值對應變量名"Email",而標籤的內部文字InnerText就是Display元數據的Name屬性對應的值"E-mail"。

DisplayFor 和 EditorFor顯示和編輯Model數據

元數據在ASP.NET MVC的一個最主要的應用就是可以通過Model來控制數據顯示和修改時所生成的HTML元素的類型。在HtmlHelper中DisplayFor是用來顯示數據的,而EditorFor是用來編輯數據的。它們都會根據元數據對數據的描述生成不同類型的HTML元素。

將Simple改成如下代碼:

複製代碼
using System.ComponentModel.DataAnnotations;
namespace SlarkInc.Models
{    
    public class Simple
    {
        [Display(Name = "Name")]       
        public string Name { get; set; }

        [Display(Name = "E-mail")]
        [DataType(DataType.EmailAddress)]       
     public string Email { get; set; } } }
複製代碼

代碼中黃色部分是對Email數據類型的描述。它的數據類型是郵件地址EmailAddress。在View中寫下如下代碼:

@Html.DisplayFor(m => m.Email)
@Html.EditorFor(m => m.Email)

DisplayFor和EditorFor都將Model的Email屬性作爲自己的參數。運行結果如下:

對應的代碼如下:

<a href="mailto:[email protected]">[email protected]</a>
<input class="text-box single-line" id="Email" name="Email" type="email" value="[email protected]" />

 從結果中可以看到由於數據類型是EmailAddress,其在顯示數據時就生成了一個發送郵件的超鏈接。在編輯數據時就生成了一個email專用的輸入框<input type="email">。

思考題

學而不思則罔,思而不學則殆。這裏出幾個思考題供大家檢驗學習效果。

1.HtmlHelper生成Form有幾種方法?分別怎麼寫?

2.如何自定義一個能生成<img>元素的HtmlHelper函數。

3.LableFor、DisplayFor、EditorFor函數用法有什麼異同?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章