Tải bản đầy đủ (.pdf) (34 trang)

22 chuong 22 tủ tài liệu bách khoa

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.45 MB, 34 trang )

Chương 22
Templated Helper
Method
Những HTML helper trong chương trước, chẳng hạn như Html.CheckBoxFor và
Html.TextBoxFor, tạo ra một loại element cụ thể, tôi phải quy định trước loại
element được sử dụng cho model và cập nhật view một cách thủ công nếu thuộc tính
thay đổi.
Trong chương này, tôi sẽ chỉ cho bạn templated helper method, tôi chỉ cần khai báo
các thcuộ tính và để cho MVC Framework tìm ra HTML element phù hợp. Đây là
cách tiếp cận linh hoạt hơn trong việc hiển thị dữ liệu, mặc dù nó đòi hỏi cao khi
thiết lập. Bảng 22-1 tóm tắt cho chương này.
Bảng 22-1. Tòm tắt chương
Vấn đề
Tạo element có thể được sử dụng
để chỉnh sửa thuộc tính model
Tạo label read-only đại diện cho
thuộc tính của tính mô hình
Tạo các element từ một đối tượng
model hoàn chỉnh

Giải quyết
Helper Html.Editor và
Html.EditorFor
Helper Html.Label và
Html.Display
Helper DisplayForModel,
EditorForModel và
LabelForModel
Giấu một phần tử khỏi người dùng Áp dụng thuộc tính
hoặc không cho phép chỉnh sửa khi HiddenInput cho trường
tạo các element bằng cách sử dụng


một whole-model helper
Tạo label sẽ được sử dụng để hiển Thuộc tính DisplayName và
thị các thuộc tính model
Display

Ví dụ
1-5, 18
6-8
9-10

11-12

13


Tùy chỉnh cách mà các thuộc tính
của model được hiển thị
Tùy chỉnh template được sử dụng
để hiển thị thuộc tính của model
Tạo model metadata tách biệt với
model type
Thay đổi element được tạo ra từ
thcuộ tính của model

Thuộc tính DataType

14

Thuộc tính UIHint


15

Tạo một lớp buddy và sử dụng
thuộc tính MetadataType
Tạo một custom template

16-17
19-22

Chuẩn bị Project mẫu
Trong chương này ta sẽ tiếp tục sử dụng project HelperMethod trong Chương 21.
Trong project đó, tôi tạo ra một class model Person như trong Ví dụ 22-1.
Ví dụ 22-1. Nội dung của file Person.cs
using System;
namespace HelperMethods.Models
{
public class Person
{
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
}
}

Project chứa một Home controller đơn giản mà tôi sử dụng để hiển thị form và nhận
form trả về. Bạn có thể xem HomeController trong Ví dụ 22-2.



Ví dụ 22-2. Nội dung của file HomeController.cs
using System.Web.Mvc;
using HelperMethods.Models;
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(person);
}
}
}

Đây là hai action method CreatePerson tôi sẽ sử dụng trong chương này, cả hai
được dùng cho file view /Views/Home/CreatePerson.cshtml. Trong Ví dụ
22-3, bạn có thể xem view CreatePerson ở chương trước, có một sự thay đổi đơn
giản.


Ví dụ 22-3. Nội dung của file CreatePerson.cshtml
@model HelperMethods.Models.Person
@{
ViewBag.Title = "CreatePerson";
Layout = "/Views/Shared/_Layout.cshtml";
Html.EnableClientValidation(false);
}

CreatePerson


@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="Submit" />
}

Tôi thêm một dòng in đậm. Theo mặc định, các helper method sẽ thêm dữ liệu của
thuộc tính cho HTML element mà nó tạo ra để hỗ trợ validate form (ứng dụng
SportsStore). Nhưng tơi không muốn sử dụng những thuộc tính đó trong chương
này, nên tôi đã sử dụng hàm Html.EnableClientValidation để vô hiệu hóa
chúng trong view CreatePerson. Các tính năng client validate vẫn được kích hoạt
cho phần còn lại của ứng dụng và tôi sẽ giải thích làm thế nào validation làm việc
(bao gồm mục đích của thuộc tính data) trong Chương 25.

Sử dụng Templated Helper Method
Các templated helper method đầu tiên mà tôi sẽ dùng là Html.Editor và

Html.EditorFor. Các Editor method nhận một tham số string để chỉ ra thuộc
tính nào sẽ được chỉnh sửa. Các helper sẽ tìm kiếm (tôi đã mô tả trong chương 20)
để xác định vị trí một thuộc tính tương ứng trong view bag và view model. Phương
pháp EditorFor cho phép bạn sử dụng một biểu thức lambda để xác định một thuộc
tính của model mà bạn muốn dùng element để chỉnh sửa nó.


Trong Ví dụ 22-4, bạn có thể thấy tôi đã áp dụng cả hai helper method Editor và
EditorFor trong view CreatePerson. Như tôi đã đề cập trong chương trước, tôi
thích sử dụng strongly typed helper vì chúng làm giảm nguy cơ gây ra lỗi khi đánh
nhầm tên thuộc tính, nhưng tôi đã sử dụng cả hai loại trong bảng ví dụ này chỉ ra
rằng bạn có thể kết hợp chúng nếu như bạn thấy phù hợp.
Ví dụ 22-4. Sử dụng helper method Editor và EditorFor trong file
CreatePerson.cshtml
@model HelperMethods.Models.Person
@{
ViewBag.Title = "CreatePerson";
Layout = "/Views/Shared/_Layout.cshtml";
Html.EnableClientValidation(false);
}

CreatePerson


@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="Submit" />
}

Các HTML element được tạo ra bằng các hàm Editor và EditorFor đều giống
nhau. Sự khác biệt chỉ là cách mà bạn chỉ ra những thuộc tính mà các editor element
sẽ tạo ra để chỉnh sửa chúng. Bạn có thể xem kết quả của những thay đổi bằng cách
chạy ứng dụng ví dụ và điều hướng đến URL /Home/CreatePerson, như trong
hình 22-1.


Hình 22-1. Sử dụng các method helper Editor và EditorFor trong một form
Ngoài việc bổ sung thuộc tính BirthDate, nó không khác với form mà tôi đã tạo
ra trong Chương 21. Tuy nhiên, có một sự thay đổi khá đáng kể, mà bạn có thể thấy
nếu bạn sử dụng một trình duyệt khác. Trong hình 22-2, bạn có thể thấy cùng một
URL hiển thị trong trình duyệt Opera.



Hình 22-2. Hiển thị một form được tạo ra bằng cách sử dụng helper method
Editor và EditorFor.
Chú ý rằng các element cho các thuộc tính PersonId và BirthDate sẽ trông
khác. Các element PersonId có spinner arrow (cho phép bạn tăng và giảm các giá
trị) và các element BirthDate được hiển thị với một bảng chọn ngày.
HTML5 định nghĩa của các input element khác nhau có thể được sử dụng để chỉnh
sửa các loại dữ liệu phổ biến, chẳng hạn như số và ngày tháng. Method Helper và
HelperFor sử dụng loại thuộc tính tôi muốn chỉnh sửa để chọn input element.
Bạn có thể thấy điều này trong Ví dụ 22-5, HTML được tạo ra cho form.
Ví dụ 22-5. Các HTML element tạo bởi người helper method Editor và
EditorFor
<!DOCTYPE html>


<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>CreatePerson</title>
<style type="text/css">
label { display: inline-block; width: 100px;}
.dataElem { margin: 5px;}
</style>
</head>
<body>

CreatePerson


data-formType="person" method="post">
<div class="dataElem">
<label>PersonId</label>

type="number" value="0" />
</div>
<div class="dataElem">
<label>First Name</label>
name="FirstName"
type="text" value="" />
</div>
<div class="dataElem">
<label>Last Name</label>
type="text" value="" />
</div>
<div class="dataElem">
<label>Role</label>
type="text" value="Admin" />
</div>
<div class="dataElem">
<label>Birth Date</label>
name="BirthDate"
type="datetime" value="01/01/0001 00:00:00" />
</div>
<input type="submit" value="Submit" />
</form>
</body>
</html>


Các thuộc tính type xác định được loại input elemnt sẽ được hiển thị bởi trình
duyệt. Các helper method đã quy định các type number và datetime cho
PersonId và text cho BirthDate, text là mặc định cho các thuộc tính khác. Lý
do mà chúng ta chỉ nhìn thấy những type này ở Opera là vì các tính năng HTML5
vẫn không được hỗ trợ rộng rãi, ngay cả trong các phiên bản mới nhất của Internet
Explorer và Chrome.


Mẹo. Hầu hết các bộ công cụ giao diện web đều có date picker, bạn có thể sử
dụng chúng thay vì dựa vào các HTML5 input element. Nếu bạn chưa có một bộ
công cụ như vậy cho dự án, tôi đề nghị bạn bắt đầu với jQuery UI
(), là một bộ công cụ mã nguồn mở, được xây dựng trên jQuery.
Bạn có thể thấy rằng bằng cách sử dụng các templated helper method tôi đã có thể
chỉnh các element từ hình thức đến nội dung, mặc dù không phải là một cách quá
hữu ích, một phần vì không phải tất cả các trình duyệt có thể hiển thị các HTML5
input element và một phần vì một số thuộc tính, chẳng hạn như Role, không được
hiển thị tốt. Tôi sẽ cho bạn thấy làm thế nào để cung cấp cho MVC Framework thông
tin bổ sung để cải thiện HTML mà các helper method tạo ra. Nhưng trước hết hãy
xem những templated helper method khác. Bạn có thể xem toàn bộ các helper
method trong Bảng 22-2 và tôi sẽ giải thích các helper trong phần tiếp theo.
Bảng 22-2. Các MVC Templated HTML Helper
Helper
Display

Ví dụ

Miêu tả
Html.Display("FirstName") Tạo một read-only view cho các
thuộc tính mô hình, chọn HTML
element dựa trên type của thuộc

tính và metadata
Phiên bản strongly typed của
DisplayFor Html.DisplayFor(x =>
x.FirstName)
helper trên
Html.Editor("FirstName") Tạo một editor cho các thuộc tính
Editor
mô hình, chọn HTML element
dựa trên type của thuộc tính và
metadata
Phiên bản strongly typed của
EditorFor Html.EditorFor(x =>
x.FirstName)
helper trên
Html.Label("FirstName")
Label
Tạo một HTML <label>
element cho thuộc tính của model
Html.LabelFor(x =>
Phiên bản strongly typed của
LabelFor
x.FirstName)
helper trên


Tạo Label và Display Element
Để chỉ cho bạn các helper method khác, tôi sẽ thêm một action method và view mới
để tạo một read-only view cho dữ liệu được submit từ form. Trước tiên, tôi sẽ làm
mới HttpPost của action CreatePerson trong bộ Home controller, như trong Ví
dụ 22-6.

Ví dụ 22-6. Tạo một view khác trong file HomeController.cs
using System.Web.Mvc;
using HelperMethods.Models;
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);
}
}
}

Tôi thêm file view DisplayPerson.cshtml vào thư mục /Views/Home, xem nội
dung của tập tin này trong Ví dụ 22-7.
Ví dụ 22-7. Nội dung của file DisplayPerson.cshtml

@model HelperMethods.Models.Person
@{
ViewBag.Title = "DisplayPerson";
Layout = "/Views/Shared/_Layout.cshtml";
}

DisplayPerson


<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>

Bạn có thể thấy view mới khi chạy ứng dụng, điều hướng đến URL

/Home/CreatePerson, điền vào form và nhấp vào nút Submit. Kết quả được thể
hiện trong hình 22-3 và bạn có thể thấy có một số thay đổi, vì helper Label và
LabelFor chỉ sử dụng tên thuộc tính làm nội dung cho label.

Hình 22-3. Sử dụng helper để tạo ra một read-only view của các đối tượng
Person
Bạn có thể nhìn thấy kết quả của những helper method trong Ví dụ 22-8. Chú ý rằng
mặc định thì các method Display và DisplayFor này không tạo ra HTML
element. Nó chỉ hiển thị giá trị của các thuộc tính.


Ví dụ 22-8. HTML được tạo ra từ view DisplayPerson
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>DisplayPerson</title>
<style type="text/css">
label { display: inline-block; width: 100px;}
.dataElem { margin: 5px;}
</style>
</head>
<body>

DisplayPerson


<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>
01/01/0001 00:00:00
</div>
</body>
</html>

Mặc dù những helper có thể có vẻ không hữu ích vào lúc này, nhưng tôi sẽ chỉ cho
bạn cách cải thiện trong thời gian ngắn.

Sử dụng Whole-Model Templated Helpers
Tôi đã sử dụng templated helper cho một thuộc tính duy nhất, nhưng các MVC
Framework hiểu rằng helper hoạt động trên toàn bộ đối tượng, một quá trình được
gọi là scaffolding. Những scaffolding helper có sẵn trong Bảng 22-3.


Bảng 22-3. Các MVC Scaffolding Templated Helper Method
Helper
Ví dụ

Miêu tả
DisplayForModel Html.DisplayForModel() Tạo một read-only view cho
toàn bộ đối tượng model
EditorForModel Html.EditorForModel() Tạo các editor element cho
toàn bộ đối tượng model
Html.LabelForModel()
LabelForModel
Tạo một HTML <label> liên
kết với đối tượng model
Mẹo. scaffolding này không giống với cái được Microsoft thêm vàoVisual Studio
để tạo ra các thành phần MVC như controller và view, nhưng ý tưởng cơ bản thì như
nhau trong đó kết quả được tạo ra dựa trên kiểu dữ liệu. Trong trường hợp của Visual
Studio, kết quả từ scaffolding là một class hoặc tập tin Razor và đầu ra của templated
helper là HTML.
Trong Ví dụ 22-9, bạn có thể thấy cách sử dụng các helper method LabelForModel
và EditorForModel để đơn giản hóa view CreatePerson.cshtml.
Ví dụ 22-9. Sử dụng các Scaffolding Helper Method trong file CreatePerson.cshtml
@model HelperMethods.Models.Person
@{
ViewBag.Title = "CreatePerson";
Layout = "/Views/Shared/_Layout.cshtml";
Html.EnableClientValidation(false);
}

CreatePerson: @Html.LabelForModel()


@using(Html.BeginRouteForm("FormRoute", new {}, FormMethod.Post,
new { @class = "personClass", data_formType="person"})) {
@Html.EditorForModel()
<input type="submit" value="Submit" />
}


Bạn có thể thấy kết quả của scaffolding helper trong hình 22-4. Một lần nữa, helper
cho ra kết quả không như mong đợi. Helper LabelForModel đã tạo ra một label
không tốt. Mặc dù có nhiều thuộc tính của các đối tượng model được hiển thị hơn
những cái tôi đã tạo bằng tay trong ví dụ trước, nhưng không phải tất cả mọi thứ đều
được hiển thị (chẳng hạn như thuộc tính Address) và những gì hiển thị không phải
lúc nào cũng hữu ích (như các thuộc tính Role, select element sẽ tốt hơn input
element).


Hình 22-4. Sử dụng scaffolding helper để tạo ra một editor cho các đối tượng
model Person
Một phần của vấn đề là các HTML mà những scaffolding helper tạo ra không tương
ứng với CSS mà tôi định nghĩa trong file /Views/Shared/_Layout.cshtml
trong chương trước. Dưới đây là một ví dụ của HTML được tạo ra để chỉnh sửa
thuộc tính FirstName:
...
<div class="editor-label">
<label for="FirstName">FirstName</label>
</div>
<div class="editor-field">
type="text" value="" />
</div>
...

Tôi có thể làm gọn view bằng cách dùng scaffolding helper để thêm CSS vào các
input và div bằng thuộc tính class. Trong Ví dụ 22-10, bạn có thể thấy những thay
đổi tôi thực hiện cho các tập tin _Layout.cshtml.



Ví dụ 22-10. Thay đổi CSS được định nghĩa trong file _Layout.cshtml
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
<style type="text/css">
label { display: inline-block; width: 100px; }
div.dataElem { margin: 5px; }
h2 > label { width: inherit; }
.editor-label, .editor-field { float: left; margin-top: 10px;}
.editor-field input { height: 20px; }
.editor-label { clear: left;}
.editor-field { margin-left: 10px; }
input[type=submit] { float: left; clear: both; margin-top: 10px; }
.column { float: left; margin: 10px;}
</style>
</head>
<body>
@RenderBody()
</body>
</html>

Kết quả như trong hình 22-5.

Hình 22-5. Kết quả của việc thêm style cho element bằng scaffolding helper
method.



Sử dụng Model Metadata
Như bạn đã thấy, những templated helper không có kiến thức về các ứng dụng và
các model data type, vì vậy nó tạo ra HTML không như ta mong muốn. Cần phải
nâng cao chất lượng đầu ra của các helper method trước khi sử dụng.
Không thể đổ lỗi cho templated helper trong trường hợp này; HTML được tạo ra dựa
trên dự đoán tốt nhất về những gì tôi muốn. Đây là vấn đề gặp với tất cả các
scaffolding. May mắn thay, những templated helper có thể được cải thiện bằng cách
sử dụng model metadata để cung cấp hướng dẫn làm thế nào để xử lý các loại model.
Metadata được dùng bằng cách sử dụng thuộc tính C#, các thuộc tính và các giá trị
tham số cung cấp hướng dẫn cho view helper. Metadata được áp dụng cho class
model, mà các helper method sử dụng khi tạo ra HTML. Trong các phần sau, tôi chỉ
cho bạn cách sử dụng metadata để hỗ trợ cho những helper trong việc tạo ra label,
editor, và hiển thị.

Sử dụng Metadata cho Control Editing và Visibility
Trong class Person, thuộc tính PersonId không thể xem hoặc chỉnh sửa. Hầu hết
các class model có ít nhất một thuộc tính như vậy, thường liên quan đến việc lưu trữ,
là một khóa chính được quản lý bởi một cơ sở dữ liệu quan hệ (ví dụ ứng dụng
SportsStore). Ta có thể sử dụng các thuộc tính HiddenInput, để helper tạo ra
một input ẩn. Bạn có thể trong Ví dụ 22-11.
Ví dụ 22-11. Sử dụng thuộc tính HiddenInput trong file Person.cs
using System;
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; }
} /
/ ... other types omitted for brevity...
}


Khi thuộc tính này đã được áp dụng, những helper Html.EditorFor và
Html.EditorForModel sẽ tạo một read-only view dựa trên thuộc tính trang trí,
như thể hiện trong hình 22-6.

Hình 22-6. Tạo một read-only field trong editor
Giá trị của thuộc tính PersonId được hiển thị, nhưng người dùng không thể chỉnh
sửa nó. HTML được tạo ra như sau:
...
<div class="editor-field">
0
<input id="PersonId" name="PersonId" type="hidden" value="0" />
</div>
...

Giá trị của thuộc tính (0 trong trường hợp này) được tạo cứng, nhưng helper cũng
thêm một input ẩn cho thuộc tính, để đảm bảo rằng mọi giá trị của form sẽ được
submit. Xem them về model binding trong Chương 24 và model validation trong
Chương 25. Nếu tôi muốn ẩn một thuộc tính hoàn toàn, sau đó tôi có thể thiết lập
giá trị của thuộc tính DisplayValue thành false, như trong Ví dụ 22-12.
Ví dụ 22-12. Sử dụng thuộc tính HiddenInput để ẩn một trường trong File

Person.cs
...
public class Person
{
[HiddenInput(DisplayValue = false)]
public int PersonId { get; set; }
public string FirstName { get; set; }


public
public
public
public
public

string LastName { get; set; }
DateTime BirthDate { get; set; }
Address HomeAddress { get; set; }
bool IsApproved { get; set; }
Role Role { get; set; }

}
...

Khi tôi sử dụng các helper Html.EditorForModel trên một đối tượng Person,
một input ẩn sẽ được tạo ra để các giá trị của PersonId sẽ được gửi khi submit
form, nhưng các label và value sẽ bị bỏ qua. Nó tác dụng giấu PersonId khỏi
người sử dụng, như trong Hình 22-7.

Hình 22-7. Ẩn thuộc tính của đối tượng model

Vẫn có thể tạo ra các input ẩn cho PersonId bằng cách sử dụng các helper
Html.EditorFor, như thế này:
...
@Html.EditorFor(m => m.PersonId)
...

Các thuộc tính HiddenInput sẽ được phát hiện, và nếu DisplayValue là true,
thì HTML sau đây được tạo ra:
...
<input id="PersonId" name="PersonId" type="hidden" value="1" />
...


LOẠI MỘT TRƯỜNG RA KHỎI SCAFFOLDING
Để loại trừ hoàn toàn một trường khỏi HTML, ta sử dụng thuộc tính
ScaffoldColumn. Trong khi thuộc tính HiddenInput có giá trị trong một input
ẩn, thuộc tính ScaffoldColumn có thể loại bỏ một trường khỏi quá trình
scaffolding. Dưới đây là một ví dụ về các thuộc tính được sử dụng:
...
[ScaffoldColumn(false)]
public int PersonId { get; set; }
...

Khi scaffolding helper thấy các thuộc tính ScaffoldColumn như thế này, nó sẽ bỏ
qua trường đó hoàn toàn; không có input ẩn được tạo ra, và không có hiện diện của
thuộc tính này được tạo trong HTML. HTML được tạo ra sẽ giống như khi sử dụng
các thuộc tính HiddenInput, nhưng không có giá trị của trường được trả về khi
submit. Điều này có ảnh hưởng đến model binding, trong Chương 24. Thuộc tính
ScaffoldColumn không hoạt động trên helper đơn, như EditorFor. Nếu tôi gọi
@Html.EditorFor (m => m.PersonId) trong một view, một editor cho các

trường PersonId sẽ được tạo ra, ngay cả khi thuộc tính ScaffoldColumn tồn tại.

Sử dụng Metadata cho Label
Theo mặc định, các Label, LabelFor, LabelForModel, và helper
EditorForModel sử dụng tên thuộc tính như nội dung cho label nó tạo ra. Ví dụ,
nếu tôi tạo một label bằng cách này:
...
@Html.LabelFor(m => m.BirthDate)
...

Kết quả sẽ là:
...
<label for="BirthDate">BirthDate</label>
...

Tất nhiên, tên của thuộc tính thường không hợp để hiển thị cho người sử dụng. Vậy
nên, tôi có thể áp dụng thuộc tính DisplayName từ namespace
System.ComponentModel.DataAnnotations, đặt giá trị tôi muốn hiển thị
thông qua thuộc tính Name. Ví dụ 22-13, thuộc tính này áp dụng cho lớp Person.


Ví dụ 22-13. Sử dụng thuộc tính DisplayName để tạo một Label trong file
Person.cs
using System;
using System.Web.Mvc;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
namespace HelperMethods.Models
{
[DisplayName("New Person")]

public class Person
{
[HiddenInput(DisplayValue = false)]
public int PersonId { get; set; }
[Display(Name = "First")]
public string FirstName { get; set; }
[Display(Name = "Last")]
public string LastName { get; set; }
[Display(Name = "Birth Date")]
public DateTime BirthDate { get; set; }
public Address HomeAddress { get; set; }
[Display(Name = "Approved")]
public bool IsApproved { get; set; }
public Role Role { get; set; }
}
// ...other types omitted for brevity...
}

Khi label helper tạo một label cho trường BirthDate, nó sẽ tìm thuộc tính
Display và sử dụng giá trị của thuộc tính Name làm text của label:
...
<label for="BirthDate">Birth Date</label>
...

Những helper cũng nhận ra thuộc tính DisplayName, có thể được tìm thấy trong
namespace System.ComponentModel. Thuộc tính này có lợi thế là có thể được áp
dụng cho class, cho phép ta sử dụng các helper Html.LabelForModel. Bạn có thể
xem các sử dụng thuộc tính này cho class Person trong ví dụ. (Ta có thể áp dụng
thuộc tính DisplayName cho mọi trường, nhưng tôi thường sử dụng thuộc tính này
cho các model class, chỉ là thói quen.) Bạn có thể thấy tác dụng của Display and

DisplayName trong hình 22-8.


Sử dụng Metadata cho các Data Value
Tôi cũng có thể sử dụng metadata để hỗ trợ việc hiển thị thuộc tính của model. Tôi
có thể sử dụng để trường BirthDate từ việc hiển thị cả giờ sang chỉ hiện thỉ ngày.
Tôi kiểm soát cách dữ liệu được hiển thị bằng cách sử dụng thuộc tính DataType,
bạn có thể thấy trong Ví dụ 22-14.
Ví dụ 22-14. Áp dụng thuộc tính DataType trong file Person.cs
...
[DisplayName("New Person")]
public class Person
{
[HiddenInput(DisplayValue = false)]
public int PersonId { get; set; }
[Display(Name = "First")]
public string FirstName { get; set; }
[Display(Name = "Last")]
public string LastName { get; set; }
[Display(Name = "Birth Date")]
[DataType(DataType.Date)]
public DateTime BirthDate { get; set; }
public Address HomeAddress { get; set; }
[Display(Name = "Approved")]
public bool IsApproved { get; set; }
public Role Role { get; set; }
}
...



Thuộc tính DataType nhận một giá trị từ DataType enum làm tham số. Trong ví
dụ tôi đã dùng DataType.Date, để templated helper tạo ra giá trị của trường
BirthDate chỉ có ngày mà không có giờ, như trong hình 22-9.

Hình 22-9. Sử dụng thuộc tính DataType để kiểm soát việc hiển thị giá trị
DateTime
Mẹo. Sự thay đổi rõ rệt khi sử dụng một trình duyệt Web có hỗ trợ input HTML5
tốt.
Bảng 22-4 Mô tả các giá trị hữu ích nhất của DataType enumeration.
Bảng 22-4. Các giá trị của DataType Enumeration
Giá trị
DateTime

Miêu tả
Hiển thị ngày tháng và thời gian (đây là mặc định cho
System.DateTime)
Hiển thị phần ngày
Date
Hiển thị phần thời gian
Time
Hiển thị một dòng chữ
Text
Hiển thị số điện thoại
PhoneNumber
MultilineText Gán giá trị vào một textarea
Hiển thị dữ liệu đã được dấu
Password
Url
Hiển thị dữ liệu như URL (sử dụng HTML element a)
EmailAddress Hiển thị dữ liệu như địa chỉ e-mail (bằng cách sử dụng một

element a với một mailto href)
Ảnh hưởng của các giá trị này phụ thuộc vào loại trường liên quan và các helper
đang được sử dụng. Ví dụ, giá trị MultilineText sẽ làm helper thay vì tạo ra
editor cho trường thì sẽ tạo một textarea, nhưng nó sẽ bị bỏ qua bởi display


helper. Các textarea cho phép người dùng chỉnh sửa một giá trị, nhưng không có
có tác dụng nhiều khi dữ liệu hiển thị trong read-only form. Tương tự, giá trị Url
chỉ có hiệu quả chỉ trên những display helper tạo ra HTML element a để tạo liên kết.

Sử dụng Metadata để chọn một Display Template
Như tên gọi của chúng, những templated helper sử dụng display template để tạo
HTML. Các template được sử dụng dựa vào loại trường được xử lý và loại helper
đang được sử dụng. Tôi có thể sử dụng thuộc tính UIHint để tuỳ chỉnh template
được sử dụng để tạo HTML cho một trường, như trong Ví dụ 22-15.
Ví dụ 22-15. Sử dụng thuộc tính UIHint trong file Person.cs
...
[DisplayName("New Person")]
public class Person
{
[HiddenInput(DisplayValue = false)]
public int PersonId { get; set; }
[Display(Name = "First")]
[UIHint("MultilineText")]
public string FirstName { get; set; }
[Display(Name = "Last")]
public string LastName { get; set; }
[Display(Name = "Birth Date")]
[DataType(DataType.Date)]
public DateTime BirthDate { get; set; }

public Address HomeAddress { get; set; }
[Display(Name = "Approved")]
public bool IsApproved { get; set; }
public Role Role { get; set; }
}
...

Trong ví dụ trên, tôi đã sử dụng MultilineText template, nó sẽ tạo một
textarea cho FirstName khi được sử dụng với một trong những editor helper,
như EditorFor hoặc EditorForModel. Bảng 22-5 cho thấy các thiết lập cho các
template tích hợp sẵn của MVC Framework.
Bảng 22-5. Các MVC Framework View Template
Giá trị
Boolean

Chỉnh sửa
Tạo checkbox, khi null thì tạo thêm
một lựa chọn Not Set

Hiển thị
Read-only, thêm
thuộc tính
disabled


Collection

Decimal
DateTime
Date

EmailAddress

Tạo template thích hợp cho mỗi phần
tử trong một chuỗi IEnumerable.
Các phần tử không cần phải cùng loại.
Tạo một textbox input một dòng
Tạo một textbox input hiển thị cả
ngày và giờ có type là datetime
Tạo một textbox input hiển thị
ngày có type là date
Gán giá trị vào một textbox input

Giống bên trái

Tạo một giá trị
Tạo một giá trị ngày
giờ
Tạo một giá trị ngày

Sử dụng thẻ a và
thuộc tính href
Tại giá trị và một
HiddenInput
Tạo một input ẩn
input ẩn
Html
Gán giá trị vào một textbox input Tạo link bằng thẻ a
Tạo giá trị
MultilineText Gán giá trị vào một textarea
Tạo giá trị

Number
Tạo một input có type là number
Xem thêm sau bảng này
Xem thêm sau bảng
Object
này
Password
Tạo một textbox input có giá trị bị Tạo giá trị không bị
giấu
giấu nhưng cho phép chỉnh sửa
Tạo giá trị
String
Tạo một textbox input
Tạo giá trị
Text
Tạo một textbox input
Tạo giá trị
Tel
Tạo một input có type là tel
Time
Tạo một textbox input hiển thị giờ Tạo một giá trị giờ
có type là time
Url
Tạo một textbox input
Tạo thẻ a, nội dung
và giá trị của href
đều được gán
Cảnh báo. Chú ý khi sử dụng các thuộc tính UIHint. Sẽ có exception khi sử dụng
template không thể hoạt động trên trường được áp dụng, ví dụ, áp dụng Boolean
template cho một trường string.

Các Object template là một trường hợp đặc biệt. Đó là các template được sử dụng
bởi những scaffolding helper để tạo ra HTML cho một view model. Template này


×