1. 程式人生 > >在 ASP.NET MVC 中建立自定義 HtmlHelper 控制元件

在 ASP.NET MVC 中建立自定義 HtmlHelper 控制元件

概述

在ASP.NET MVC框架中已經封裝了很多基於Html標準的Html控制元件,我們可以方便的使用這些控制元件輸出想要的內容,使開發變得快捷。

例如ASP.NET MVC框架包括以下設定標準的HTML控制元件(部分控制元件):

  • Html.ActionLink()
  • Html.BeginForm()
  • Html.CheckBox()
  • Html.DropDownList()
  • Html.EndForm()
  • Html.Hidden()
  • Html.ListBox()
  • Html.Password()
  • Html.RadioButton()
  • Html.TextArea()
  • Html.TextBox()


1.
在ASP.NET MVC應用程式的開發中,我們常碰到類似Html.Label或Html.TextBox這樣的程式碼,它將在網頁上產生一個label或input標記。這些HtmlHelper的擴充套件方法有些像WebForm中的控制元件,只需傳入一些引數即可生成相應的HTML程式碼。本文將介紹建立HtmlHelper的方法。

Html.Textbox方法的返回值是MvcHtmlString,它生成了一些HTML程式碼。建立HtmlHelper,就像在生成HTML程式碼。下面以一個帶有簡要描述功能的連結HtmlHelper為例介紹建立自定義HtmlHelper的方法。它將顯示一個連結並在下方簡要介紹該與該連結內容有關的資訊。在某些帶有簡要描述的項列表頁上可能會需要類似的功能。最後的結果預覽如下圖。


上面使用了3次自定義的HtmlHelper,每次生成的程式碼如下

1 <div>
2 <p class="LinkTitle"><a href="#">連結標題</a></p>
3 <p class="LinkDescription">連結描述</p>
4 </div>
 

可能稍微有點複雜,因為有了標籤的巢狀。

做好準備工作以後,新建一個靜態類LinkWithDescriptionExtensions,新增靜態方法LinkWithDescription,程式碼如下

程式碼 
 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;

namespace MvcApp.Web.CustomerControllers
{
    public static class HtmlHelpersExtensions
    {
        /// <summary>  
        /// 獲取值時:value值為1表示男,value值為2表示女  
        /// 預設選中男  
        /// </summary>  
        /// <param name="helper"></param>
        /// <param name="defaultChecked"></param>  
        /// <returns></returns>  
        public static MvcHtmlString LabelGender(this HtmlHelper helper, string defaultChecked = "male")
        {
            StringBuilder str = new StringBuilder();
            str.AppendFormat("<input type='radio' name='sex' value=1 {0}></input>",
                             defaultChecked == "male" ? "checked='checked'" : string.Empty);
            str.AppendFormat("<label for='{0}'>{1}</label>", "male", "男"); // 顯示男性值  
            str.AppendFormat("<input type='radio' name='sex' value=2 {0} ></input>",
                             defaultChecked == "female" ? "checked='checked'" : string.Empty);
            str.AppendFormat("<label for='{0}'>{1}</label>", "female", "女"); // 顯示女性值  
            return new MvcHtmlString(str.ToString());
        }

        /// <summary>
        /// 帶描述的連結擴充套件方法
        /// </summary>
        /// <param name="htmlHelper">要擴充套件的HtmlHelper類</param>
        /// <param name="title">標題</param>
        /// <param name="url">連結地址</param>
        /// <param name="description">描述</param>
        /// <returns>HTML程式碼</returns>
        public static MvcHtmlString LinkWithDescription(this HtmlHelper htmlHelper, string title, string url,
                                                        string description)
        {
            // 生成與標題連結有關的HTML程式碼
            TagBuilder titleContainer = new TagBuilder("p"); // 標題連結容器p
            TagBuilder titleLink = new TagBuilder("a"); // 標題中的文字要有連結,所以包含在a標籤內
            titleLink.MergeAttribute("href", url); // 為a新增href屬性並指定連結地址
            titleLink.SetInnerText(title); // 標題文字
            titleContainer.InnerHtml = titleLink.ToString(); // 將a放到p中
            titleContainer.AddCssClass("LinkTitle"); // 為標題新增樣式

            // 生成與連結描述有關的HTML程式碼
            TagBuilder descriptionContainer = new TagBuilder("p"); // 連線描述容器p
            descriptionContainer.InnerHtml = description; // 描述文字
            descriptionContainer.AddCssClass("LinkDescription"); // 為描述新增樣式

            // 將上述元素放入一個DIV中
            TagBuilder div = new TagBuilder("div");
            div.InnerHtml = string.Format("{0}{1}", titleContainer.ToString(), descriptionContainer.ToString());
            // 返回生成的HTML程式碼
            return MvcHtmlString.Create(div.ToString());
        }

    }
}

先理清結構再使用TagBuilder生成HTML程式碼是比較方便的。這裡也可以使用拼接字串的方式來生成HTML程式碼,只要最後得到所需的HTML程式碼就可以,但是我個人不建議使用拼接字串的方式,這樣不僅思維容易混亂而且容易出錯。使用TagBuilder既結構清晰,又不容易出錯。

在ASPX頁中,可以使用
<%@ Import Namespace="MvcApp.Web.Controllers" %>

1 <%:Html.LinkWithDescription("測試連結1", "#", "這是測試連結1的描述")%>
2 <%:Html.LinkWithDescription("測試連結2", "#", "這是測試連結2的描述")%>
3 <%:Html.LinkWithDescription("測試連結3", "#", "這是測試連結3的描述")%>
 

來呼叫上面的擴充套件方法,這裡的連結標題、連結地址和描述等資訊可以通過ViewData等方式傳入。在Action中寫

程式碼
 1 /// <summary>
 2 /// Demo
 3 /// </summary>
 4 /// <returns>Demo檢視</returns>
 5 public ActionResult Demo()
 6 {
 7     // 建立連結資訊列表
 8     List<LinkInfo> links = new List<LinkInfo>();
 9     links.Add(new LinkInfo { Description = "這是測試連結1的描述", Title = "測試連結1", Url = "#" });
10     links.Add(new LinkInfo { Description = "這是測試連結2的描述", Title = "測試連結2", Url = "#" });
11     links.Add(new LinkInfo { Description = "這是測試連結3的描述", Title = "測試連結3", Url = "#" });
12
13
14     ViewData["Links"] = links;
15
16     return View();
17 }
 

在ASPX頁中寫
<%@ Import Namespace="MvcApp.Web.Controllers" %>

1 <%List<LinkInfo> links=ViewData["Links"] as List<LinkInfo>;
2 foreach (var link in links)
3 {   %>
4 <%:Html.LinkWithDescription(link.Title, link.Url, link.Description)%>
5 <%} %>


2.
在asp.net mvc 中每一個Html控制元件都返回了MvcHtmlString ,他繼承了HtmlString。
下面自定義一個關於顯示男女性別的自定義Html控制元件,使在建立頁面時,可以直接呼叫該自定義的Html控制元件。
可以檢視其他的Html控制元件返回的是HtmlHelper,所以自定義的時候也要返回相同的型別
直接在Controls資料夾下建立要自定義的html控制元件
程式碼如下:

此類要返回的value值也可以根據引數的方式傳入
using MvcApp.Web.Controllers

在頁面中只需呼叫: @Html.LabelGender()  

顯示如圖:


注意事項:
a、注意建立類的名稱空間要與本身的@Html保持一致

b、建立的類須為靜態類,命名規則一般字尾為Extensions

能對HtmlHelper控制元件進行擴充套件,為建立自己的html標籤提供了很大的方便。

3.

Html控制元件擴充套件類

先看下面的程式碼

//// 摘要:
        //     獲取或設定 System.Web.Mvc.HtmlHelper 物件,該物件用於呈現 HTML 元素。
        //// 返回結果:
        //     用於呈現 HTML 元素的 System.Web.Mvc.HtmlHelper 物件。public HtmlHelper<TModel> Html { get; set; }
複製程式碼

這是系統對頁面上@Html屬性的定義。

我們可以看到該Html是返回了一個HtmlHelper

看到這裡我們的入口點就找到了,就是以HtmlHelper作為擴充套件型別。

繼續在建好的Controls資料夾中建立名為LabelExtensions的類和RadioButtonExtensions的類

程式碼

publicstaticclass LabelExtensions
    {
        publicstatic MvcHtmlString LKLabel(this HtmlHelper helper, string fortarget, string text)
        {
            string str = String.Format("<label for='{0}'>{1}</label>", fortarget, text);
            returnnew MvcHtmlString(str);
        }
    }

    publicstaticclass RadioButtonExtensions
    {
        publicstatic MvcHtmlString LKRadioButton(this HtmlHelper helper, string nametarget, string idtarget)
        {
            string str = String.Format("<input type='radio' name='{0}' id='{1}' />", nametarget, idtarget);
            returnnew MvcHtmlString(str);

        }
    }
複製程式碼

呼叫控制元件

此時我們再寫Html控制元件看看

頁面程式碼

@using MvcApplication.Controls;
@Html.LKLabel("male", "男")
@Html.LKRadioButton("sex", "male")
<br />
@Html.LKLabel("female", "女")
@Html.LKRadioButton("sex", "female")
複製程式碼

執行效果

總結

對於控制元件的擴充套件極大的滿足了我們在程式設計過程中的各種需求,使得我們在頁面程式設計上面變得簡單快捷。