Использование встроенных вспомогательных методов
MVC Framework включает в себя несколько встроенных вспомогательных методов, предназначенных для создания форм HTML. В следующих разделах мы рассмотрим эти вспомогательные методы в действии и научимся их использовать.
Создаем элементы form
Одним из наиболее распространенных способов взаимодействия с пользователем в веб-приложении являются HTML-формы, которые можно создавать с помощью целого ряда вспомогательных методов. Чтобы продемонстрировать методы, предназначенные для работы с формами, мы внесли некоторые дополнения в наш пример проекта. Для начала мы создали новый класс Person.cs
в папке Models
. Содержимое этого файла показано в листинге 19-12 – тип Person
будет нашей моделью представления, с помощью которой мы продемонстрируем связанные с формами вспомогательные методы, а типы Address
и Role
помогут нам продемонстрировать некоторые более сложные функции.
Листинг 19-12: Модель Person
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
, в которых будут использоваться объекты модели и которые показаны в листинге 19-13.
Листинг 19-13: Добавляем методы действий в контроллер 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"};
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);
}
}
}
Это стандартный подход к работе с HTML-формами, который включает два метода. Здесь мы полагаемся на механизм связывания данных, предполагая, что MVC Framework создаст объект Person
из данных формы и передаст его в метод действия с помощью атрибута HttpPost
. (Атрибут HttpPost
рассматривается в главе 16, а связывание данных - в главе 22).
Мы никак не обрабатываем данные формы, потому что хотим сосредоточиться на том, как генерировать элементы в представлении. Наш метод действия HttpPost
просто вызывает метод View
и передает в него объект Person
, который он получил в качестве параметра; таким образом мы отображаем пользователю введенные им в форму данные.
Для начала мы создадим стандартную HTML-форму вручную, а затем покажем вам, как заменить различные ее части с помощью вспомогательных методов. Первоначальную версию формы вы можете увидеть в листинге 19-14; в нем показано содержимое представления CreatePerson.cshtml
, которое мы создали в папке /Views/Home
.
Листинг 19-14: Первоначальная версия формы HTML
@model HelperMethods.Models.Person
@{
ViewBag.Title = "CreatePerson";
}
<h2>CreatePerson</h2>
<form action="/Home/CreatePerson" method="post">
<div class="dataElem">
<label>PersonId</label>
<input name="personId" value="@Model.PersonId"/>
</div>
<div class="dataElem">
<label>First Name</label>
<input name="FirstName" value="@Model.FirstName"/>
</div>
<div class="dataElem">
<label>Last Name</label>
<input name="lastName" value="@Model.LastName"/>
</div>
<input type="submit" value="Submit" />
</form>
Данное представление содержит стандартную форму, созданную вручную, в которой мы установили значение атрибута value
элементов input
, используя объект модели.
Подсказка
Обратите внимание, что мы установили атрибут
name
во всех элементахinput
так, чтобы он соответствовал свойству модели, которое отображается элементомinput
. Атрибутinput
используется стандартным механизмом связывания MVC Framework для того, чтобы выяснить, какие элементыinput
содержит значения для свойств типа модели во время обработки запросаpost
и, если вы не укажете атрибутname
, форма не будет работать должным образом. В главе 22 мы подробно описываем механизм связывания данных, а также способы изменения его поведения.
Мы отредактировали содержимое файла /Views/Shared/_Layout.cshtml
, как показано в листинге 19-15, чтобы максимально упростить данный пример. Мы удалили теги Razor @Scripts
и @Styles
, которые будут описаны в главе 24.
Листинг 19-15: Упрощаем макет
<!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;
}
.dataElem {
margin: 5px;
}
</style>
</head>
<body>
@RenderBody()
</body>
</html>
Чтобы увидеть базовую функциональность формы, запустите приложение и перейдите по ссылке /Home/CreatePerson
. HTML-форма с примерами данных показана на рисунке 19-6. Так как данные формы никак не используются в приложении, то после нажатия на кнопку Submit
они будут просто отображаться пользователю.
Рисунок 19-6: Используем простую форму HTML в приложении

В листинге 19-16 показан код HTML, который приложение направило в браузер; мы будем его использовать, чтобы продемонстрировать изменения, вызванные применением вспомогательных методов.
Листинг 19-16: Код 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;
}
.dataElem {
margin: 5px;
}
</style>
</head>
<body>
<h2>CreatePerson</h2>
<form action="/Home/CreatePerson" method="post">
<div class="dataElem">
<label>PersonId</label>
<input name="personId" value="0" />
</div>
<div class="dataElem">
<label>First Name</label>
<input name="FirstName" />
</div>
<div class="dataElem">
<label>Last Name</label>
<input name="lastName" />
</div>
<input type="submit" value="Submit" />
</form>
</body>
</html>
Примечание
Используя вспомогательные методы, не обязательно генерировать такие HTML-элементы, как
form
иinput
. Если хотите, вы можете закодировать их, используя статические HTML-теги, и заполнить значения с помощью объектовViewData
илиViewModel
, как это cделали мы в данном разделе. В следующих разделах мы покажем, как с помощью вспомогательных методов создать чистый HTML-код без каких-либо специальных значений атрибутов. Это не означает, что вы обязаны их использовать, но с их помощью очень легко гарантировать, что HTML будет находиться в синхронизации с приложением, так что, например, изменения в конфигурации будут автоматически отражаться в формах. Вспомогательные методы нужно использовать для удобства, а не потому, что они создают особенный или специальный HTML-код, и вас никто не принуждает их использовать, если они не соответствуют вашему стилю разработки.
Создаем элементы form
Два из наиболее полезных (и наиболее часто используемых) вспомогательных метода - это Html.BeginForm
и Html.EndForm
. Они создают теги формы HTML и генерируют для нее допустимый атрибут action
, основываясь на механизме маршрутизации приложения.
Существует 13 различных версий метода BeginForm
, что позволяет нам очень точно указать, как должен быть сгенерирован элемент формы. Для нашего приложения потребуется самая базовая версия, которая не принимает аргументов. Она создает элемент формы, атрибут action
которого гарантирует, что форма будет отправлена к тому же методу действия, который визуализировал текущее представление. В листинге 19-17 показано, как мы применили эту перегруженную версию BeginForm
, а также вспомогательный метод EndForm
(для EndForm
есть только одно определение, и он просто закрывает элемент формы, добавляя в представление </form>
).
Листинг 19-17: Используем вспомогательные методыBeginForm
иEndForm
@model HelperMethods.Models.Person
@{
ViewBag.Title = "CreatePerson";
}
<h2>CreatePerson</h2>
@Html.BeginForm()
<div class="dataElem">
<label>PersonId</label>
<input name="personId" value="@Model.PersonId"/>
</div>
<div class="dataElem">
<label>First Name</label>
<input name="FirstName" value="@Model.FirstName"/>
</div>
<div class="dataElem">
<label>Last Name</label>
<input name="lastName" value="@Model.LastName"/>
</div>
<input type="submit" value="Submit" />
@{ Html.EndForm(); }
Обратите внимание, что мы должны были обработать вызов к вспомогательному методу EndForm
как оператор C#, так как метод EndForm
записывает свой тег непосредственно в вывод, а не возвращает результат, который можно добавить в представление, как это делает BeginForm
.
С точки зрения дизайна решение просто ужасное, но это не имеет значения, потому что метод EndForm
используется редко. Более распространенный подход показан в листинге 19-18, где вызов к вспомогательному методу BeginForm
заключается в выражение using
. В конце блока using
среда выполнения .NЕТ вызывает для объекта, который возвращается методом BeginForm
, метод Dispose
, который и вызывает метод EndForm
.
(Чтобы увидеть, как это работает, загрузите исходный код MVC Framework и рассмотрите класс System.Web.Mvc.Html.FormExtensions
).
Листинг 19-18: Создаем самозакрывающуюся форму
@model HelperMethods.Models.Person
@{
ViewBag.Title = "CreatePerson";
}
<h2>CreatePerson</h2>
@using (Html.BeginForm())
{
<div class="dataElem">
<label>PersonId</label>
<input name="personId" value="@Model.PersonId"/>
</div>
<div class="dataElem">
<label>First Name</label>
<input name="FirstName" value="@Model.FirstName"/>
</div>
<div class="dataElem">
<label>Last Name</label>
<input name="lastName" value="@Model.LastName"/>
</div>
<input type="submit" value="Submit" />
}
Этот подход, известный как самозакрывающаяся форма (self-closing form), мы чаще всего используем в своих проектах – нам нравится то, что форма содержится в блоке кода и становится ясно, какие элементы будут находиться между открывающим и закрывающим тегами формы.
Остальные 12 версий метода BeginForm
позволяют изменять различные аспекты элемента формы. В этих перегруженных версиях есть много повторов, так как они указывают различные детали, касающиеся создания формы. В таблице 19-4 мы перечислили наиболее важные версии, которые вы будете использовать в приложениях регулярно. Другие перегруженные версии метода BeginForm
нужны для совместимости с версиями MVC Framework, которые были выпущены до того, как в C# появилась поддержка создания динамических объектов.
Таблица 19-4: Перегруженные версии вспомогательного метода BeginForm
Перегруженная версия | Описание |
BeginForm() |
Создает форму, которая отправляет данные в метод действия, который ее сгенерировал. |
BeginForm(action, controller) |
Создает форму, которая отправляет данные в метод действия и контроллер, указанные в параметрах. |
BeginForm(action, controller, method) |
Как и предыдущие перегруженные версии, но позволяет указать значение атрибута method , используя значение из перечисления System.Web.Mvc.FormMethod .
|
BeginForm(action, controller, method, attributes) |
Как и предыдущие перегруженные версии, но позволяет задавать атрибуты элемента формы с помощью объекта, свойства которого используются в качестве имен атрибутов. |
BeginForm(action, controller, routeValues, method, attributes) |
Как и предыдущие перегруженные версии, но позволяет вам указать значения для сегментов переменных маршрутов в конфигурации маршрутизации в приложении с помощью объекта, свойства которого соответствуют переменным маршрутизации. |
Мы показали вам простейший вариант метода BeginForm
, который полностью подходит для нашего приложения. В листинге 19-19 показана самая сложная версия, в которой мы указали дополнительную информацию для создания элемента формы.
Листинг 19-19: Используем самую сложную перегруженную версию метода BeginForm
@model HelperMethods.Models.Person
@{
ViewBag.Title = "CreatePerson";
}
<h2>CreatePerson</h2>
@using (Html.BeginForm("CreatePerson", "Home",
new { id = "MyIdValue" }, FormMethod.Post,
new { @class = "personClass", data_formType = "person" }))
{
<div class="dataElem">
<label>PersonId</label>
<input name="personId" value="@Model.PersonId"/>
</div>
<div class="dataElem">
<label>First Name</label>
<input name="FirstName" value="@Model.FirstName"/>
</div>
<div class="dataElem">
<label>Last Name</label>
<input name="lastName" value="@Model.LastName"/>
</div>
<input type="submit" value="Submit" />
}
В этом примере явно указаны некоторые детали, такие как имя действия и контроллера, которые в противном случае были бы выведены MVC Framework автоматически. Мы также уточнили, что форма должна быть отправлена с помощью метода HTTP POST
, который использовался бы в любом случае.
Самые интересные аргументы - те, которые устанавливают значения для переменных маршрута и задают атрибуты для элемента form
. С помощью аргумента значения маршрута мы указали значение переменной сегмента id
в стандартном маршруте, который был добавлен Visual Studio в файл /App_Start/RouteConfig.cs
при создании проекта. Мы также определили атрибуты class
и data
(атрибуты data
- это пользовательские атрибуты, которых можно добавлять к элементам, чтобы они обрабатывали контент HTML). Вот тег формы HTML, который генерирует этот вызов к BeginForm
:
<form action="/Home/CreatePerson/MyIdValue" class="personClass" data-formType="person"
method="post">
Как видите, значение атрибута id
было добавлено к целевому URL, а атрибуты class
и data
- к элементу формы. Обратите внимание, что в нашем вызове к BeginForm
мы указали атрибут data_formType
, но в итоге получили атрибут data-formType
. Нельзя указывать в динамическом объекте имена свойств с дефисами, поэтому мы используем символ подчеркивания, который на выходе автоматически преобразуется в дефис, аккуратно обходя несоответствие между синтаксисом C# и HTML. (И, конечно, мы должны поставить префикс @
перед именем свойства class
, чтобы использовать зарезервированное ключевое слово C# в качестве имени свойства для атрибута класса).
Определяем маршрут, который будет использоваться формой
Когда вы используете метод BeginForm
, MVC Framework будет искать в конфигурации маршрутизации первый маршрут, с помощью которого она сможет сгенерировать ссылку на запрашиваемое действие или контроллер – в общем, выбор маршрута платформа полностью берет на себя. Если вы хотите указать конкретный маршрут, можете использовать вспомогательный метод BeginRouteForm
. Чтобы продемонстрировать его работу, мы добавили новый маршрут в файл /App_Start/RouteConfig.cs
, как показано в листинге 19-20.
Листинг 19-20: Добавляем новый маршрут в файл RouteConfig.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace HelperMethods
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new
{
controller = "Home",
action = "Index",
id = UrlParameter.Optional
}
);
routes.MapRoute(
name: "FormRoute",
url: "app/forms/{controller}/{action}"
);
}
}
}
Если мы вызовем метод BeginForm
при такой конфигурации маршрутизации, то получим элемент form
с атрибутом action
, который содержит URL, созданный по стандартному маршруту. В листинге 19-21 с помощью метода BeginRouteForm
мы указали, что нужно использовать новый маршрут.
Листинг 19-21: Указываем маршрут для создания URL
@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>
<input name="personId" value="@Model.PersonId"/>
</div>
<div class="dataElem">
<label>First Name</label>
<input name="FirstName" value="@Model.FirstName"/>
</div>
<div class="dataElem">
<label>Last Name</label>
<input name="lastName" value="@Model.LastName"/>
</div>
<input type="submit" value="Submit" />
}
Теперь мы получаем тег form
, атрибут action
которого содержит URL, соответствующий нашему новому маршруту:
<form action="/app/forms/Home/CreatePerson" class="personClass"
data-formType="person" method="post">
Подсказка
Для метода
BeginRouteForm
есть целый ряд перегруженных версий, которые позволяют указывать детали элементаform
, как и для методаBeginForm
. Они повторяют структуру версийBeginForm
. Более подробную информацию можно узнать из документации API.
Создаем элементы input
Элемент HTML form
совершенно бесполезен без элементов input
. В таблице 19-5 показаны базовые вспомогательные методы для создания элементов ввода, а также приводятся примеры генерируемого ими кода HTML. Для всех этих вспомогательных методов первый аргумент присваивает значения атрибутам id
и name
элемента input
, а второй присваивает значение атрибуту value
.
Таблица 19-5: Базовые вспомогательные методы для создания элементов ввода
Элемент HTML | Пример |
Чекбокс | Html.CheckBox("myCheckbox", false)
Вывод:
<input id="myCheckbox" name="myCheckbox" type="checkbox" value="true" />
<input name="myCheckbox" type="hidden" value="false" /> |
Скрытое поле | Html.Hidden("myHidden", "val")
Вывод:
<input id="myHidden" name="myHidden" type="hidden" value="val" /> |
Переключатель | Html.RadioButton("myRadiobutton", "val", true)
Вывод:
<input checked="checked" id="myRadiobutton" name="myRadiobutton"
type="radio" value="val" /> |
Пароль | Html.Password("myPassword", "val")
Вывод:
<input id="myPassword" name="myPassword" type="password" value="val" /> |
Текстовая область (многострочное текстовое поле) | Html.TextArea("myTextarea", "val", 5, 20, null)
Вывод:
<textarea cols="20" id="myTextarea" name="myTextarea" rows="5">
val</textarea> |
Текстовое поле | Html.TextBox("myTextbox", "val")
Вывод:
<input id="myTextbox" name="myTextbox" type="text" value="val" /> |
Все эти вспомогательные методы являются перегруженными версиями. В таблице показан самый простой вариант, но, чтобы создать атрибуты HTML, вы можете указать дополнительные объекты, как мы это делали в предыдущем разделе для элемента form
.
Примечание
Обратите внимание, что вспомогательный метод для чекбокса (
Html.CheckBox
) визуализирует два элементаinput
. Он визуализирует чекбокс и скрытый элемент ввода с таким же названием. Это необходимо потому, что браузеры не отправляют значения чекбокса, если он не был отмечен. Наличие скрытого элемента управления гарантирует, что в таких случаях MVC Framework получит значение из скрытого поля.
В листинге 19-22 показано, как мы использовали базовые вспомогательные методы для создания элементов ввода.
Листинг 19-22: Используем базовые вспомогательные методы для создания элементов ввода
@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.TextBox("personId", @Model.PersonId)
</div>
<div class="dataElem">
<label>First Name</label>
@Html.TextBox("firstName", @Model.FirstName)
</div>
<div class="dataElem">
<label>Last Name</label>
@Html.TextBox("lastName", @Model.LastName)
</div>
<input type="submit" value="Submit" />
}
Элементы HTML input
, которые генерирует это представление, показаны в листинге 19-23. Вывод очень похож на наш первоначальный элемент form
, но здесь уже появились некоторые намеки на MVC Framework – например, атрибуты data
, которые добавляют валидацию формы (валидацию мы рассматривали в главе 2 и вернемся к этой теме в главе 23).
Листинг 19-23: Элементы input
, созданные с помощью базовых вспомогательных методов ввода
<form action="/app/forms/Home/CreatePerson" class="personClass" data-formtype="person"
method="post">
<div class="dataElem">
<label>PersonId</label>
<input data-val="true" data-val-number="The field PersonId must be a number."
data-val-required="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>
<input type="submit" value="Submit" />
</form>
Подсказка
Чтобы создать атрибуты
data
, которые поддерживают валидацию форм для всего приложения, установите параметруUnobtrusiveJavaScriptEnabled
значениеfalse
в файлеWeb.config
. Отключить эту функцию для отдельных представлений можно вызовомHtml.EnableClientValidation(false)
в блоке кода Razor. Пример этого вы сможете увидеть в главе 23, где мы отключим атрибутыdata
, чтобы создавать элементы HTML с помощью более продвинутых вспомогательных методов.
Создаем элемент input из свойства модели
Вспомогательные методы, которые мы использовали в предыдущем разделе, неплохо справляются со своими обязанностями, но мы все еще должны гарантировать, что значение первого аргумента соответствует значению модели, которую мы передаем в качестве второго аргумента. В противном случае MVC Framework не сможет восстановить объект модели из данных формы, поскольку атрибуты name
и значения forms
элементов input
не будут совпадать.
Для каждого из методов, перечисленных в таблице 19-5, существует альтернативная перегруженная версия, которая принимает строковый аргумент single
, который мы использовали в листинге 19-24.
Листинг 19-24: Создаем элемент input
с помощью имени свойства модели
@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.TextBox("PersonId")
</div>
<div class="dataElem">
<label>First Name</label>
@Html.TextBox("firstName")
</div>
<div class="dataElem">
<label>Last Name</label>
@Html.TextBox("lastName")
</div>
<input type="submit" value="Submit" />
}
Аргумент string
используется для поиска в ViewData
, ViewBag
и ViewModel
данных, которые используются для создания элемента input
. Так, например, если вы вызываете @Html.TextBox("DataValue")
, MVC Framework попытается найти какие-либо данные, которые соответствуют ключу DataValue
. Проверяются следующие адреса:
ViewBag.DataValue
;@Model.DataValue
.
Первое найденное значение используется для установки значения атрибута value
генерируемого элемента HTML. (Последний адрес, @Model.DataValue
, проверяется, только если модель представления содержит свойство или поле под названием DataValue
.)
Если указать строку вида DataValue.First.Name
, поиск станет более сложным. MVC Framework будет проверять различные адреса, в который First
и Name
будут записаны по-разному, например:
ViewBag.DataValue.First.Name
ViewBag.DataValue["First"].Name
ViewBag.DataValue["First.Name"]
ViewBag.DataValue["First"]["Name"]
Напомним, что будет использовано первое найденное значение, на котором поиск будет остановлен. Очевидно, это решение сделано для оптимизации производительности, но, как правило, ViewBag
содержит немного значений, так что их проверка не занимает много времени.
Используем строго типизированные вспомогательные методы ввода
Для каждого из базовых вспомогательных методов ввода, которые мы описали в таблице 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)
</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>
|
Раскрывающийся список | 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>
|
Список множественного выбора | Html.ListBoxFor(x => x.Vals, new MultiSelectList(new [] {"A", "B"}))
Вывод:
<select id="Vals" multiple="multiple" name="Vals">
<option>A</option>
|
Вспомогательные методы select
принимают параметры SelectList
или MultiSelectList
. Разница между этими классами заключается в том, что для MultiSelectList
есть опции конструктора, которые позволяют указать, что при первоначальной загрузке страницы необходимо выбрать более одного пункта.
Оба эти классы работают с последовательностью объектов IEnumerable
. В таблице 19-7 мы создали внутренние массивы, которые содержат пункты списка, но SelectList
и MultiSelectList
будут извлекать значения для пунктов списка из объектов, в том числе из объекта модели. Как видите, мы создали элемент select
для свойства Role
модели Person
в листинге 19 - 26.
Листинг 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" data-formtype="person"
method="post">
<div class="dataElem">
<label>PersonId</label>
<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>