Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ASP_NET_MVC_4_Framework_s_primerami_na_C_dlya_p

.pdf
Скачиваний:
29
Добавлен:
19.03.2016
Размер:
17.66 Mб
Скачать

Используем строго типизированные вспомогательные методы ввода

Для каждого из базовых вспомогательных методов ввода, которые мы описали в таблице 19-5, имеются соответствующие строго типизированные версии. Они показаны в таблице 19-6 вместе с примерами кода HTML, который они генерируют.

Эти вспомогательные методы используются только в строго типизированных представлениях. (Для краткости мы опустили из таблицы некоторые вспомогательные методы, которые генерируют атрибуты валидации форм на стороне клиента.)

Таблица 19-6: Строго типизированные вспомогательные методы ввода

Элемент HTML

Чекбокс

Скрытое поле

Переключатель

Пароль

Текстовая

область

Текстовое поле

Пример

Html.CheckBoxFor(x => x.IsApproved) Вывод: <input id="IsApproved" name="IsApproved" type="checkbox" value="true" /> <input name="IsApproved" type="hidden" value="false" />

Html.HiddenFor(x => x.FirstName) Вывод: <input id="FirstName" name="FirstName" type="hidden" value="" />

Html.RadioButtonFor(x => x.IsApproved, "val") Вывод: <input id="IsApproved" name="IsApproved" type="radio" value="val" />

Html.PasswordFor(x => x.Password) Вывод: <input id="Password" name="Password" type="password" />

Html.TextAreaFor(x => x.Bio, 5, 20, new{}) Вывод: <textarea cols="20" id="Bio" name="Bio" rows="5">Bio value</textarea>

Html.TextBoxFor(x => x.FirstName) Вывод: <input id="FirstName" name="FirstName" type="text" value="" />

Строго типизированные вспомогательные методы ввода работают с лямбда-выражениями. Значение, которое передается в выражение, - это объект модели представления, и вы можете выбрать поле или свойство, которое будет использоваться для установки атрибута value. В листинге 19-25 показано, как мы использовали этот вид вспомогательных методов в представлении CreatePerson.cshtml.

Листинг 19-25: Используем типизированные вспомогательные методы ввода

@model HelperMethods.Models.Person @{

ViewBag.Title = "CreatePerson";

}

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

501

</div>

<div class="dataElem"> <label>Last Name</label>

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

</div>

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

}

Сгенерированный ими HTML ничем не отличается, но мы предпочитаем использовать строго типизированные вспомогательные методы потому, что они снижают риск возникновения ошибки изза опечатки в имени свойства.

Создаем элементы select

В таблице 19-7 показаны вспомогательные методы, которые используются для создания элементов select. С их помощью можно создать элемент, позволяющий выбрать один пункт из раскрывающегося списка, или элемент множественного выбора, который позволяет выбрать несколько пунктов. Как для других элементов форм, для этих вспомогательных методов существуют слабо и строго типизированные версии.

Таблица 19-7: Вспомогательные методы HTML, которые визуализируют элементы выбора

Элемент HTML

Пример

 

Html.DropDownList("myList", new SelectList(new [] {"A", "B"}),

Раскрывающийся

"Choose") Вывод: <select id="myList" name="myList"> <option

список

value="">Choose</option> <option>A</option>

 

<option>B</option> </select>

Раскрывающийся

Html.DropDownListFor(x => x.Gender, new SelectList(new [] {"M",

"F"})) Вывод: <select id="Gender" name="Gender"> <option>M</option>

список

<option>F</option> </select>

 

Список

Html.ListBox("myList", new MultiSelectList(new [] {"A", "B"})) Вывод:

множественного

<select id="myList" multiple="multiple" name="myList">

<option>A</option>

выбора

 

 

<option>B</option> </select>

Список

Html.ListBoxFor(x => x.Vals, new MultiSelectList(new [] {"A", "B"}))

Вывод: <select id="Vals" multiple="multiple" name="Vals">

множественного

<option>A</option>

выбора

 

 

<option>B</option> </select>

Вспомогательные методы select принимают параметры SelectList или MultiSelectList. Разница между этими классами заключается в том, что для MultiSelectList есть опции конструктора, которые позволяют указать, что при первоначальной загрузке страницы необходимо выбрать более одного пункта.

Оба эти классы работают с последовательностью объектов IEnumerable. В таблице 19-7 мы создали внутренние массивы, которые содержат пункты списка, но SelectList и MultiSelectList будут извлекать значения для пунктов списка из объектов, в том числе из объекта модели. Как видите, мы создали элемент select для свойства Role модели Person в листинге 19 - 26.

502

Листинг 19-26: Создаем элемент select для свойства Person.Role

@model HelperMethods.Models.Person @{

ViewBag.Title = "CreatePerson";

}

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

}

Мы определили свойство Role, используя значение из перечисления Role, определенного в том же классе. Поскольку объекты SelectList и MultiSelectList работают на объектах IEnumerable, мы должны применить метод Enum.GetNames, чтобы использовать Role enum в качестве источника для элемента select. В листинге 19-27 показан код HTML, который создает наше обновленное представление, в том числе элемент select.

Листинг 19-27: Код HTML, который создает представление CreatePerson

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

}

.dataElem { margin: 5px;

}

</style>

</head>

<body>

<h2>CreatePerson</h2>

<form action="/app/forms/Home/CreatePerson" class="personClass" dataformtype="person"

method="post">

<div class="dataElem"> <label>PersonId</label>

503

<input data-val="true" data-val-number="The field PersonId must be a number." data-valrequired="

The PersonId field is required."

id="PersonId" name="PersonId" type="text" value="0" /> </div>

<div class="dataElem"> <label>First Name</label>

<input id="FirstName" name="FirstName" type="text" value="" /> </div>

<div class="dataElem"> <label>Last Name</label>

<input id="LastName" name="LastName" type="text" value="" /> </div>

<div class="dataElem"> <label>Role</label>

<select data-val="true" data-val-required="The Role field is required." id="Role" name="Role">

<option selected="selected">Admin</option> <option>User</option> <option>Guest</option>

</select>

</div>

<input type="submit" value="Submit" /> </form>

</body>

</html>

Резюме

В этой главе мы рассмотрели вспомогательные методы, которые можно использовать для создания блоков контента в представлениях. Мы показали вам, как создавать собственные внутренние и внешние вспомогательные методы, а затем рассмотрели встроенные вспомогательные методы, с помощью которых можно создавать элементы HTML form, input и select. В следующей главе мы продолжим рассматривать эту тему и научимся использовать шаблонные вспомогательные методы.

504

Шаблонные вспомогательные методы

Вспомогательные методы HTML, которые мы рассмотрели в предыдущей главе (такие как Html.CheckBoxFor и Html.TextBoxFor), генерируют определенный тип элемента. Это значит, что мы должны заранее решить, какой элемент будет представлять данное свойство модели, и вручную обновлять представления, если тип свойства изменится.

В этой главе мы рассмотрим шаблонные вспомогательные методы, которые позволяют нам только указать свойство, которое мы хотим визуализировать, не уточняя, какой элемент HTML для него требуется - это MVC Framework выяснит самостоятельно. Это более гибкий подход к отображению данных пользователю, хотя он и требует немного больше внимания и осторожности.

Обзор проекта для примера

В этой главе мы продолжим использовать проект HelperMethod, который создали в главе 19. Здесь у нас есть класс модели Person и пара сопровождающих типов. Чтобы легче было вспомнить, мы перечислили их в листинге 20-1.

Листинг 20-1: Типы Person, Address и Role

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

}

}

Пример проекта содержит очень простой контроллер Home, с помощью которого мы отображаем формы и получаем данные от них. Определение класса HomeController показано в листинге 20-2.

505

Листинг 20-2: Класс HomeController

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

}

}

}

В этой главе мы будем использовать два метода действий CreatePerson, каждый из которых визуализирует представление /Views/Home/CreatePerson.cshtml. В листинге 20-3 показано представление CreatePerson, которое мы создали в конце главы 19.

Листинг 20-3: Представление CreatePerson

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

}

506

В него мы внесли одно изменение, которые выделено жирным шрифтом. По умолчанию, вспомогательные методы добавляют атрибуты data к HTML-элементам, таким образом обеспечивая валидацию форм, которую мы рассмотрели в главе 9 на примере приложения SportsStore. В этой главе мы не хотим их использовать, так что мы отключили их для представления CreatePerson с помощью метода Html.EnableClientValidation. Для остальной части приложения валидация на стороне клиента по-прежнему активирована. Подробно механизм валидации (в том числе и назначение data-атрибутов) мы рассмотрим в главе 23.

Использование шаблонных вспомогательных методов

Для начала мы рассмотрим шаблонные вспомогательные методы Html.Editor и Html.EditorFor. Метод Editor принимает аргумент string, определяющий свойство, для которого требуется элемент editor; он проводит поиск соответствующего свойства в ViewBag и объекте модели (данный процесс был описан в главе 18).

Метод EditorFor является его строго типизированным эквивалентом, в котором свойство модели, необходимое для элемента editor, указывается с помощью лямбда-выражения.

В листинге 20-4 показано, как вспомогательные методы Editor и EditorFor используются в представлении CreatePerson. Как мы уже упоминали в главе 19, мы предпочитаем использовать строго типизированные вспомогательные методы, так как они снижают риск возникновения ошибки из-за опечатки в имени свойства; в этом листинге мы использовали оба типа, просто чтобы показать, что вы можете смешивать и сочетать методы так, как считаете нужным.

Листинг 20-4: Используем методы Editor и 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="Submit" />

507

}

Editor и EditorFor создают идентичные элементы HTML; единственное различие между ними – это способ записи свойства, для которого создаются элементы editor. Вы можете увидеть результат применения этих методов, запустив приложение и перейдя по ссылке Home/CreatePerson, как показано на рисунке 20-1.

Рисунок 20-1: Используем методы Editor и EditorFor в форме

Не считая свойства BirthDate, эта форма по виду не отличается от формы, которую мы создали в главе 19. Тем не менее, изменения в ней довольно существенные; их можно увидеть, открыв страницу в другом браузере. На рисунке 20-2 показана та же страница в браузере Opera (www.opera.com).

Рисунок 20-2: Отображение формы, созданной с помощью вспомогательных методов Editor и EditorFor

508

Обратите внимание, что элементы для свойств PersonId и BirthDate выглядят по-другому. У элемента PersonId появились стрелки (которые позволяют увеличивать и уменьшать значение) а элемент BirthDate теперь позволяет выбрать дату.

В спецификации HTML5 определены различные типы элементов input, которые используются для редактирования общих типов данных, таких как числа и даты. Методы Editor и EditorFor выбирают один из этих новых типов, основываясь на типе свойства, которое мы хотим отредактировать. В листинге 20-5 показан код HTML, который был создан для формы на рисунках

20-1 и 20-2.

Листинг 20-5: Элементы HTML input, созданные вспомогательными методами Editor и EditorFor

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

}

.dataElem { margin: 5px;

}

</style>

</head>

<body>

<h2>CreatePerson</h2>

<form action="/app/forms/Home/CreatePerson" class="personClass" data-formtype="person" method="post">

<div class="dataElem"> <label>PersonId</label>

<input class="text-box single-line" id="PersonId" name="PersonId" type="number" value="0" />

</div>

<div class="dataElem"> <label>First Name</label>

<input class="text-box single-line" id="FirstName" name="FirstName" type="text" value="" />

</div>

<div class="dataElem"> <label>Last Name</label>

<input class="text-box single-line" id="LastName" name="LastName" type="text" value="" />

</div>

<div class="dataElem"> <label>Role</label>

<input class="text-box single-line" id="Role" name="Role" type="text" value="Admin" />

</div>

<div class="dataElem"> <label>Birth Date</label>

<input class="text-box single-line" id="BirthDate" name="BirthDate" type="datetime" value="01/01/0001 00:00:00" />

</div>

<input type="submit" value="Submit" /> </form>

</body>

</html>

509

Атрибут type указывает, какой элемент input должен быть отображен. Для свойств PersonId and BirthDate во вспомогательных методах указаны типы number и datetime, для других свойств типом по умолчанию является text. Мы видим эти типы только в Opera по той причине, функции HTML5 все еще довольно новые и не все браузеры их поддерживают (в том числе Internet Explorer 10, который мы используем для скриншотов в этой книге).

Как видите, с помощью шаблонных вспомогательных методов мы смогли создать элементы формы, соответствующие контенту. Хотя в данном примере они были не особенно полезны, так как не все браузеры отображают типы элементов input HTML5, а также некоторые свойства, такие как Role, отображаются не так, как нам хотелось бы. Далее мы продемонстрируем, как обеспечить MVC Framework дополнительную информацию и улучшить код HTML, генерируемый вспомогательными методами. Но прежде чем мы углубимся в детали, давайте рассмотрим другие шаблонные вспомогательные методы. В таблице 20-1 приведен полный список вспомогательных методов, которые мы рассмотрим по отдельности в следующих разделах.

Таблица 20-1: Шаблонные вспомогательные методы MVC

Вспомогательный

Пример

 

Описание

метод

 

 

 

 

 

 

 

 

 

 

 

Визуализирует нередактируемый элемент HTML

Display

Html.Display("FirstName")

 

для указанного свойства модели в соответствии

 

 

 

с типом свойства и метаданными.

DisplayFor

Html.DisplayFor(x => x.FirstName)

Editor Html.Editor("FirstName")

Строго типизированная версия предыдущего метода.

Отображает элемент editor (редактируемый элемент HTML) для указанного свойства модели в соответствии с типом свойства и метаданными.

EditorFor

Html.EditorFor (x =>

 

Строго типизированная версия предыдущего

x.FirstName)

 

метода.

 

 

 

 

 

 

Label

Html.Label("FirstName")

 

Отображает HTML-элемент <label> для

 

указанного свойства модели

 

 

 

 

 

 

 

LabelFor

Html.LabelFor (x =>

 

Строго типизированная версия предыдущего

x.FirstName)

 

метода.

 

 

Создаем элементы label и display

Чтобы продемонстрировать другие вспомогательные методы, мы добавим в приложение новое представление, которое будет визуализировать нередактируемые элементы на основе данных, полученных из формы. Для начала мы обновили версию HttpPost действия CreatePerson контроллера Home, как показано в листинге 20-6.

Листинг 20-6: Указываем новое представление в контроллере Home

using System.Web.Mvc;

using HelperMethods.Models;

namespace HelperMethods.Controllers

{

public class HomeController : Controller

{

public ActionResult Index()

{

ViewBag.Fruits = new string[] {"Apple", "Orange", "Pear"};

510

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]