010_模板輔助器方法

来源:http://www.cnblogs.com/KeSaga/archive/2016/06/02/5554589.html
-Advertisement-
Play Games

相比輔助器方法,模板輔助器方法更智能一些,它們可以指定想要顯示的屬性,而讓MVC框架去判斷應該使用什麼樣的HTML元素。只是,需要一些初期關註才能建立起來,但畢竟是一種顯示數據的更為靈活的方式。 這裡打算繼續使用介紹輔助器方法時使用的項目,但是,CreatePerson.cshtml視圖在之前的輔助 ...


         相比輔助器方法,模板輔助器方法更智能一些,它們可以指定想要顯示的屬性,而讓MVC框架去判斷應該使用什麼樣的HTML元素。只是,需要一些初期關註才能建立起來,但畢竟是一種顯示數據的更為靈活的方式。

         這裡打算繼續使用介紹輔助器方法時使用的項目,但是,CreatePerson.cshtml視圖在之前的輔助器方法會在生成的HTML元素上添加data屬性,來支持表單驗證,這一點在後面對模板輔助器方法的使用時打算禁用,但是,客戶端驗證特性對程式的其他部分仍然有效,調整後的代碼如下(粗體部分為修改的內容):

@model HelperMethods.Models.Person

@{
    ViewBag.Title = "CreatePerson";
    Html.EnableClientValidation(false);
}

<h2>CreatePerson</h2>

@using (Html.BeginRouteForm("FormRoute", new { }, FormMethod.Post,
 new { @class = "personClass", data_formType = "person" })) 
{
    <div class="dataElem">
        <label>PersonId</label>
        @Html.TextBoxFor(m => m.PersonId)
    </div>
    <div class="dataElem">
        <label>First Name</label>
        @Html.TextBoxFor(m => m.FirstName)
    </div>
    <div class="dataElem">
        <label>Last Name</label>
        @Html.TextBoxFor(m => m.LastName)
    </div>
    <div class="dataElem">
        <label>Role</label>
        @Html.DropDownListFor(m => m.Role, new SelectList(Enum.GetNames(typeof(HelperMethods.Models.Role))))
    </div>
    <input type="submit" value="提交" />
}

 

 

使用模板輔助器方法

         首先來看看編輯元素的輔助器方法:Html.EditorFor和Html.Editor。Editor方法的字元串參數是用來指定編輯器元素所需的屬性的。EditorFor是強類型的輔助器方法,可以使用lambda表達式指定編輯器元素所需要的模型屬性。為了演示,下麵同時混合使用了這兩種方法,實際項目中可以根據自己的喜好使用,但是還是推薦使用EditorFor方法,這樣可以避免由誤輸屬性名造成的錯誤:

@model HelperMethods.Models.Person

@{
    ViewBag.Title = "CreatePerson";
    Html.EnableClientValidation(false);
}

<h2>CreatePerson</h2>

<!--使用模板輔助器方法-->
@using (Html.BeginRouteForm("FormRoute", new { }, FormMethod.Post, new { @class = "personClass", data_formType = "person" }))
{
    <div class="dataElem">
        <label>PersonId</label>
        @Html.Editor("PersonId")
    </div>
    <div class="dataElem">
        <label>First Name</label>
        @Html.Editor("FirstName")
    </div>
    <div class="dataElem">
        <label>Last Name</label>
        @Html.EditorFor(m => m.LastName)
    </div>
    <div class="dataElem">
        <label>Role</label>
        @Html.EditorFor(m => m.Role)
    </div>
    <div class="dataElem">
        <label>Birth Date</label>
        @Html.EditorFor(m => m.BirthDate)
    </div>
    <input type="submit" value="提交" />
}

最終效果如圖,這和之前的輔助器方法實現的一樣,只是增加了一個BirthDate的顯示:

 

         這裡的日期顯示成這個樣子,是因為我的瀏覽器的問題,預設情況下IE瀏覽器對日期的顯示不怎麼友好,如果換成其他瀏覽器(如Opera瀏覽器)就可以正常顯示,當然在IE下可以通過jQuery等一些第三方的控制項實現。所以在開發Web端程式的時候一定要註意不同瀏覽器直接的差異(對於這幾個屬性的顯示不同的還有PersonId等)。

         HTML5規範對input元素所編輯的常規的屬性類型,定義了一些不同的類型,如數字和日期,而這裡的模板輔助器方法採用的就是HTML5的新類型。下麵是我的瀏覽其中生成的HTML結果:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>CreatePerson</title>
    
    <link href="/Content/Site.css" rel="stylesheet">
    <style type="text/css">
        label {
            display: inline-block;
            width: 100px;
        }

        .dateElem {
            margin: 5px;
        }
    </style>
</head>
<body>
    

<h2>CreatePerson</h2>

<!--使用模板輔助器方法-->
<form class="personClass" action="/app/forms/Home/CreatePerson" method="post" data-formtype="person">    <div class="dataElem">
        <label>PersonId</label>
        <input name="PersonId" class="text-box single-line" id="PersonId" type="number" value="0">
    </div>
    <div class="dataElem">
        <label>First Name</label>
        <input name="FirstName" class="text-box single-line" id="FirstName" type="text" value="">
    </div>
    <div class="dataElem">
        <label>Last Name</label>
        <input name="LastName" class="text-box single-line" id="LastName" type="text" value="">
    </div>
    <div class="dataElem">
        <label>Role</label>
        <input name="Role" class="text-box single-line" id="Role" type="text" value="Admin">
    </div>
    <div class="dataElem">
        <label>Birth Date</label>
        <input name="BirthDate" class="text-box single-line" id="BirthDate" type="datetime" value="0001/1/1 0:00:00">
    </div>
    <input type="submit" value="提交">
</form>

</body>
</html>

         Type標簽屬性指定了input元素應當顯示的類型,但是,可惜不是所有的瀏覽器都能支持,原因就是HTML5特性比較新。

         後面會展示如何為MVC框架提供附加信息,以便改善輔助器方法生成的HTML,下麵先看看完整的輔助器集。

輔助器

示例

描述

Display

Html.Display ("FirstName")

渲染指定模型屬性的只讀視圖,會根據該屬性的類型及元數據選用一個HTML元素

DisplayFor

Html.DisplayFor(x => x.FirstName)

上一輔助器的強類型版本

Editor

Html.Editor("FirstName")

渲染指定模型屬性的一個編輯器,會根據該屬性的類型及元數據選用一個HTML元素

EditorFor

Html.EditorFor(x => x.FirstName)

上一輔助器的強類型版本

Label

Html.Label("FirstName")

渲染指定模型的HTML<label>元素(註意:它顯示的是指定屬性的屬性名,而非屬性值)

LabelFor

Html.LabelFor(x => x.FirstName)

上一輔助器的強類型版本

生成標簽和顯示元素

         後面對Home控制器做一下修改,用來演示這些輔助器方法:

using HelperMethods.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace HelperMethods.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            ViewBag.Fruits = new string[] { "Apple", "Orange", "Pear" };
            ViewBag.Cities = new string[] { "New York", "London", "Paris" };

            string message = "This is an HTML element: <input>";

            return View((object)message);
        }

        public ActionResult CreatePerson()
        {
            return View(new Person());
        }

        [HttpPost]
        public ActionResult CreatePerson(Person person)
        {
            return View("DisplayPerson", person);
        }

    }
}

 

         上面的DisplayPerson對應的視圖文件添加到/Views/Home文件夾中,其內容如下:

@model HelperMethods.Models.Person

@{
    ViewBag.Title = "DisplayPerson";
}

<h2>DisplayPerson</h2>

<div class="dataElem">
    @Html.Label("PersonId")
    @Html.Display("PersonId")
</div>
<div class="dataElem">
    @Html.Label("FirstName")
    @Html.Display("FirstName")
</div>
<div class="dataElem">
    @Html.LabelFor(m => m.LastName)
    @Html.DisplayFor(m => m.LastName)
</div>
<div class="dataElem">
    @Html.LabelFor(m => m.Role)
    @Html.DisplayFor(m => m.Role)
</div>
<div class="dataElem">
    @Html.LabelFor(m => m.BirthDate)
    @Html.DisplayFor(m => m.BirthDate)
</div>

         啟動程式,導航至/Home/CreatePerson後,填充內容,並點擊“提交”按鈕,便可看到下圖的結果:

 

         下麵是這些輔助器方法生成的HTML,需要註意的是,Display和DisplayFor方法預設情況下並未生成HTML元素——它們只是發佈了它們所操作的屬性值:

<!DOCTYPE html>
<html><head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>DisplayPerson</title>
    
    <link href="/Content/Site.css" rel="stylesheet">
    <style type="text/css">
        label {
            display: inline-block;
            width: 100px;
        }

        .dateElem {
            margin: 5px;
        }
    </style>
</head>
<body>
    

<h2>DisplayPerson</h2>

<div class="dataElem">
    <label for="PersonId">PersonId</label>
    100
</div>
<div class="dataElem">
    <label for="FirstName">FirstName</label>
    Adam
</div>
<div class="dataElem">
    <label for="LastName">LastName</label>
    Freeman
</div>
<div class="dataElem">
    <label for="Role">Role</label>
    Admin
</div>
<div class="dataElem">
    <label for="BirthDate">BirthDate</label>
    0001/1/1 0:00:00
</div>
</body></html>

         看似這些輔助器不是很有用,但可以做些調整來使其產生更希望顯示給用戶的輸出結果。

使用整體模型模板輔助器

   前面說的都是針對單個屬性的輔助器,其實還有一些針對整個對象的輔助器——這稱之為支架輔助器。

輔助器

示例

描述

DisplayForModel

Html.DisplayForModel()

渲染整個模型對象的只讀視圖

EditorForModel

Html.EditorForModel()

渲染整個模型對象的編輯器元素

LabelForModel

Html.LabelForModel()

渲染對整個模型對象進行引用的HTML<label>元素

註:所謂模板輔助器Templated Helper)是在視圖中使用的一種輔助性工具,用以為視圖模型的屬性生成HTML標記。模板輔助器有兩大類:一類就叫模板輔助器Templated Helper),作用是在視圖中為模型的個別屬性生成HTML標記。另一類叫作支架輔助器Scaffolding Helper),作用是在視圖中創建整個模型所有屬性HTML標記。這兩種模板輔助器又分別有三種:

  • 標簽輔助器(LabelLabelForLabelForModel),用於生成模型屬性的標簽(以屬性名稱作為標簽);
  • 顯示輔助器(DisplayDisplayForDisplayForModel),用於生成模型屬性的顯示標記(顯示屬性的值,或顯示只讀數據);
  • 編輯輔助器(EditEditForEditForModel),用於生成對模型屬性進行編輯的標記(編輯器)。

   下麵演示一下通過LabelForModel和EditForModel 輔助器簡化CreatePerson.cshtml視圖的結果:

@model HelperMethods.Models.Person

@{
    ViewBag.Title = "CreatePerson";
    Html.EnableClientValidation(false);
}

<h2>CreatePerson: @Html.LabelForModel()</h2>

@using (Html.BeginRouteForm("FormRoute", new { }, FormMethod.Post, new { @class = "personClass", data_formType = "person" }))
{
    @Html.EditorForModel()

    <input type="submit" value="提交" />
}

 

         下麵是效果,雖然還有些不太正確,主要是因為支架輔助器生成的HTML與前面的佈局視圖中CSS的定義不對應,以及它會預設顯示所有的模型中的屬性,後面做一些修改便可達到我們的目標:

 

         下麵先通過對樣式作簡單的改動,對視圖外觀加以整理,以使它們預製件輔助器添加到div和input元素中的CSS的class值對應起來。文件_Layout.cshtml修改的結果:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
    <link href="~/Content/Site.css" rel="stylesheet" />
    <style type="text/css">
        label {
            display: inline-block;
            width: 100px;
        }

        .dateElem {
            margin: 5px;
        }

        h2 > label {
            width: inherit;
        }

        .editor-label, .editor-field {
            float: left;
        }

            .editor-label, .editor-label label, .editor-field input {
                height: 20px;
            }

        .editor-label {
            clear: left;
        }

        .editor-field {
            margin-left: 10px;
            margin-top: 10px;
        }

        input[type=submit] {
            float: left;
            clear: both;
            margin-top: 10px;
        }

        .column {
            float: left;
            margin: 10px;
        }
    </style>
</head>
<body>
    @RenderBody()
</body>
</html>

 

使用模型元數據

         用前面的輔助器模板生成的HTML可以看出其並非十分智能,經常會產生不需要的HTML。但是,我們可以通過模型元數據(MetaData加以輔助,從而改善這種結果。它的實現原理是:使用C#註解屬性,以及註解屬性的參數值來為輔助器提供一定的指示,輔助器方法在生成HTML元素時將會根據這些信息進行組織。

用元數據控制編輯及可見性

         比如我們通過HiddenInput註解屬性將Person類中的PersonId屬性隱藏後,在運用這個註解屬性時,Html.EditorFor和Html.EditorForModel輔助器會生成一個對應的只讀視圖,下麵分別是代碼示例和效果圖:

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

namespace HelperMethods.Models
{
    public class Person
    {
        [HiddenInput]
        public int PersonId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime BirthDate { get; set; }
        public Address HomeAddress { get; set; }
        public bool IsApproved { get; set; }
        public Role Role { get; set; }
    }

    public class Address
    {
        public string Line1 { get; set; }
        public string Line2 { get; set; }
        public string City { get; set; }
        public string PostalCode { get; set; }
        public string Country { get; set; }
    }

    public enum Role
    {
        Admin,
        User,
        Guest
    }

}

 

          這樣得到了一個該屬性值的文本顯示效果,且在HTML中生成了一個字元串值和一個隱藏的input元素。如果不希望顯示該屬性值,可以將該註解屬性的DisplayValue參數設置為false,如:

public class Person
    {
        [HiddenInput(DisplayValue = false)]
        public int PersonId { get; set; }
        …
    }
…

 

 

         此時,即便使用的是類似Html.EditorFor這樣的針對某一屬性的模板輔助器,任會達到上面的效果。


排除支架中的一個屬性

 


 

如果不需要某一屬性生成HTML元素,可以使用ScaffoldColumn(命名空間為:System.ComponentModel.DataAnnotations)註解屬性。相對於HiddenInputScaffoldColumn是將某一屬性標記為完全禁止,即在生成HTML的時候將不會將該屬性生成對應的HTML元素,如下麵示例:

         [ScaffoldColumn(false)]

        public int PersonId { get; set; }

但是,這麼做也有一個問題,就是這對模型綁定是有影響的,而且對模板輔助器(相對於支架輔助器的那種)是不起作用的。

使用用於標簽的元數據

         預設情況下,Label、LabelFor、LabelForModel,以及EditorForMordel輔助器會以屬性名稱作為它們生成的標簽元素的內容,但實際項目中經常不希望這麼做,尤其是在中文環境的項目中。這個時候可以使用System.ComponentModel命名空間下的DisplayName註解屬性,併為其參數提供希望的值即可(同時還有System.ComponentModel.DataAnnotations中的Display註解屬性)。如:

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using Syste

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 哈哈,我又回來了,簡單的重新裝了一邊虛擬機,又把vim配置了一遍,這回有信心把youcomplete的安裝方法貼出來了,先給個權威的鏈接,然後給出具體步驟,保證沒問題可以安裝成功 http://www.centoscn.com/image-text/install/2016/0424/7115.ht ...
  • 我的機子炸了,然後我就得重新裝我的虛擬機,再然後我就想去弄好我的共用文件夾安裝vmtools,安裝的時候出現了一個問題,我忘記以前是怎麼解決的,又困擾了我好久 Searching for a valid kernel header path... The path "" is not a valid ...
  • 如何一步步點亮LED 註:實驗是基於s5pv210的板子,這篇筆記參考自《朱老師物聯網大講堂》朱老師隨堂筆記 文中提到的手冊下載鏈接:(https://yunpan.cn/OcSz7Yh35ISJK7 訪問密碼 6665;https://yunpan.cn/OcSz7SzsfS7a6p 訪問密碼 1 ...
  • 我們經常在Linux下可以看到inode,都不知道是什麼東東,那麼我們現在來慢慢瞭解下。 一、inode是什麼? 理解inode,要從文件儲存說起。 文件儲存在硬碟上,硬碟的最小存儲單位叫做"扇區"(Sector)。每個扇區儲存512位元組(相當於0.5KB)。 操作系統讀取硬碟的時候,不會一個個扇區 ...
  • 創建基本的鏈接和URL<!--?xml:namespace prefix = "o" ns = "urn:schemas-microsoft-com:office:office" /--> 在我們介紹鏈接或URL之前先做一些準備,我們這部分要介紹的知識將要使用的項目就是之前建立的HelperMeth ...
  • 0 概述 所謂同步,就是給多個線程規定一個執行的順序(或稱為時序),要求某個線程先執行完一段代碼後,另一個線程才能開始執行。 第一種情況:多個線程訪問同一個變數: 1. 一個線程寫,其它線程讀:這種情況不存在同步問題,因為只有一個線程在改變記憶體中的變數,記憶體中的變數在任意時刻都有一個確定的值; 2. ...
  • ...
  • 主要代碼,請根據實際情況修改。 Response.Write("<div id='mydiv' >"); Response.Write("_"); Response.Write("</div>"); Response.Write("<script>mydiv.innerText = '';</scr ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...