Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Авторы: Рик Андерсон (Rick Anderson), Н. Тейлор Маллен (N. Taylor Mullen), Дейв Пакетт (Dave Paquette) и Джерри Пелсер (Jerrie Pelser)
В этом документе приводятся сведения о работе с формами и элементами HTML, часто используемыми в формах. Элемент HTML форма предоставляет основной механизм, используемый веб-приложениями для отправки данных на сервер. В большей части этого документа описываются вспомогательные функции тегов и их применение для создания надежных форм HTML. Перед прочтением этого документа рекомендуется изучить статью Общие сведения о вспомогательных функциях тегов.
Во многих случаях вспомогательные функции HTML предоставляют альтернативный подход к определенному вспомогательному элементу тегов. Однако важно признать, что вспомогательные функции тегов не заменяют вспомогательные элементы HTML, и для каждого вспомогательного элемента HTML нет вспомогательного средства тегов. Если есть альтернатива вспомогательному методу HTML, она будет указана.
Вспомогательная функция тега формы
Вспомогательный объект для тега форм:
Создает значение атрибута HTML <FORM>
actionдля действия контроллера MVC или именованного маршрута.Создает скрытый маркер проверки запроса , чтобы предотвратить подделку межсайтовых запросов (при использовании с
[ValidateAntiForgeryToken]атрибутом в методе действия HTTP Post).Предоставляет атрибут
asp-route-<Parameter Name>, где<Parameter Name>добавляется в значения маршрута. ПараметрыrouteValuesдляHtml.BeginFormиHtml.BeginRouteFormпредоставляют аналогичные функциональные возможности.Имеет альтернативу
Html.BeginFormвспомогателя HTML иHtml.BeginRouteForm.
Пример:
<form asp-controller="Demo" asp-action="Register" method="post">
<!-- Input and Submit elements -->
</form>
Вспомогательный объект для тегов формы создавал следующий HTML-код:
<form method="post" action="/Demo/Register">
<!-- Input and Submit elements -->
<input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>
Среда выполнения MVC генерирует значение атрибута action на основе атрибутов вспомогательной функции тега формы asp-controller и asp-action. Вспомогательная функция тега формы также создает скрытый токен проверки запроса для предотвращения подделки межсайтовых запросов (при использовании с атрибутом [ValidateAntiForgeryToken] в методе действия HTTP Post). Защита чистой HTML-формы от межсайтовой подделки запросов является сложной задачей, но вспомогательный элемент тега формы предоставляет такую функциональность.
Использование именованного маршрута
Атрибут asp-route вспомогательной функции тега также может создавать разметку для атрибута HTML action. Приложение с маршрутом с именем register использует следующую разметку для страницы регистрации:
<form asp-route="register" method="post">
<!-- Input and Submit elements -->
</form>
Многие представления в папке Views/Account (созданные при создании веб-приложения с отдельными учетными записями) содержат атрибут asp-route-returnurl :
<form asp-controller="Account" asp-action="Login"
asp-route-returnurl="@ViewData["ReturnUrl"]"
method="post" class="form-horizontal" role="form">
Примечание.
Встроенные шаблоны returnUrl заполняются автоматически только при попытке доступа к авторизованному ресурсу, но не проходят проверку подлинности или не авторизованы. При попытке несанкционированного доступа ПО безопасности промежуточного слоя перенаправит вас на страницу входа с заданным returnUrl.
Вспомогательный объект для тега действия формы
Вспомогательная функция тега действий формы создает атрибут formaction в созданном теге <button ...> или <input type="image" ...>. Атрибут formaction определяет, куда форма отправляет свои данные. Он привязывается к элементам <input> и <button>. Вспомогательный компонент тега действий формы позволяет использовать несколько атрибутов AnchorTagHelper для управления генерируемой ссылкой для соответствующего элемента.
Ниже перечислены поддерживаемые атрибуты AnchorTagHelper для управления значением formaction.
| Атрибут | Описание |
|---|---|
| asp-controller | Имя контроллера. |
| asp-action | Имя метода действия. |
| asp-area | Имя области. |
| asp-page | Имя Razor страницы. |
| asp-page-handler | Имя обработчика Razor страницы. |
| asp-route | Имя маршрута. |
| asp-route-{value} | Одно значение URL-адреса маршрута. Например, asp-route-id="1234". |
| asp-all-route-data | Все значения маршрута. |
| asp-фрагмент | Фрагмент URL-адреса. |
Пример отправки контроллеру
Следующая разметка отправляет форму Index в действие HomeController при выборе входного или кнопки:
<form method="post">
<button asp-controller="Home" asp-action="Index">Click Me</button>
<input type="image" src="..." alt="Or Click Me" asp-controller="Home"
asp-action="Index">
</form>
Предыдущая разметка создает следующий код HTML.
<form method="post">
<button formaction="/Home">Click Me</button>
<input type="image" src="..." alt="Or Click Me" formaction="/Home">
</form>
Отправка формы в пример страницы
Следующая разметка пересылает форму на страницу AboutRazor:
<form method="post">
<button asp-page="About">Click Me</button>
<input type="image" src="..." alt="Or Click Me" asp-page="About">
</form>
Предыдущая разметка создает следующий код HTML.
<form method="post">
<button formaction="/About">Click Me</button>
<input type="image" src="..." alt="Or Click Me" formaction="/About">
</form>
Добавить в пример маршрута
Рассмотрим конечную точку /Home/Test.
public class HomeController : Controller
{
[Route("/Home/Test", Name = "Custom")]
public string Test()
{
return "This is the test page";
}
}
Разметка ниже отправляет форму в конечную точку /Home/Test.
<form method="post">
<button asp-route="Custom">Click Me</button>
<input type="image" src="..." alt="Or Click Me" asp-route="Custom">
</form>
Предыдущая разметка создает следующий код HTML.
<form method="post">
<button formaction="/Home/Test">Click Me</button>
<input type="image" src="..." alt="Or Click Me" formaction="/Home/Test">
</form>
Вспомогательная функция тега входных данных
Вспомогатель тега ввода привязывает элемент ввода HTML <> к выражению модели в представлении razor.
Синтаксис
<input asp-for="<Expression Name>">
Помощник тега ввода
Создает атрибуты HTML
idиnameдля имени выражения, указанного в атрибутеasp-for.asp-for="Property1.Property2"эквивалентнаm => m.Property1.Property2. Имя выражения используется в качестве значения атрибутаasp-for. Дополнительные сведения см. в разделе "Имена выражений ".Задает значение атрибута HTML
typeна основе типа модели и атрибутов заметки данных , применяемых к свойству модели.Не перезаписывает значение атрибута HTML
type, если оно уже задано.Создает атрибуты проверки HTML5 из атрибутов заметки данных , применяемых к свойствам модели.
Имеется пересечение функции вспомогательного компонента HTML с
Html.TextBoxForиHtml.EditorFor. Дополнительные сведения см. в разделе Альтернативы использования HTML для вспомогательного тега ввода.Обеспечивает строгую типизацию. Если имя свойства изменяется, и вы не обновляете вспомогательный тег, вы получите ошибку, аналогичную следующей:
An error occurred during the compilation of a resource required to process this request. Please review the following specific error details and modify your source code appropriately. Type expected 'RegisterViewModel' does not contain a definition for 'Email' and no extension method 'Email' accepting a first argument of type 'RegisterViewModel' could be found (are you missing a using directive or an assembly reference?)
Вспомогательная функция тега Input задает атрибут HTML type на основе типа .NET. В следующей таблице перечислены некоторые распространенные типы .NET и созданный тип HTML (указаны не все типы .NET).
| Тип .NET | Тип ввода |
|---|---|
| Булев | type="checkbox" |
| Строка | type="text" |
| Дата/время | type="datetime-local" |
| Байт | type="number" |
| int | type="number" |
| Одинарный, Двойной | type="number" |
В следующей таблице приведены некоторые наиболее распространенные атрибуты заметок к данным, которые вспомогательная функция тега входных данных будет сопоставлять с определенными типами входных данных (указаны не все атрибуты проверки):
| Атрибут | Тип ввода |
|---|---|
| [EmailAddress] | type="email" |
| [URL-адрес] | type="url" |
| [HiddenInput] | type="hidden" |
| [Телефон] | type="телефон" |
| [DataType(DataType.Password)] | type="password" |
| [ТипДанных(ТипДанных.Дата)] | type="date" |
| [DataType(DataType.Time)] | type="time" |
Пример:
using System.ComponentModel.DataAnnotations;
namespace FormsTagHelper.ViewModels
{
public class RegisterViewModel
{
[Required]
[EmailAddress]
[Display(Name = "Email Address")]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
}
}
@model RegisterViewModel
<form asp-controller="Demo" asp-action="RegisterInput" method="post">
<label>Email: <input asp-for="Email" /></label> <br />
<label>Password: <input asp-for="Password" /></label><br />
<button type="submit">Register</button>
</form>
Предыдущий код вызывает следующий код HTML:
<form method="post" action="/Demo/RegisterInput">
Email:
<input type="email" data-val="true"
data-val-email="The Email Address field is not a valid email address."
data-val-required="The Email Address field is required."
id="Email" name="Email" value=""><br>
Password:
<input type="password" data-val="true"
data-val-required="The Password field is required."
id="Password" name="Password"><br>
<button type="submit">Register</button>
<input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>
Заметки данных применяются к свойствам Email и Password, создающим метаданные для модели. Вспомогательный объект Input Tag использует метаданные модели и создает атрибуты HTML5 (см. статью о проверке модели). Эти атрибуты описывают валидаторы, присоединяемые к входным полям. Это обеспечивает ненавязчивую проверку HTML5 и jQuery. Ненавязчивые атрибуты имеют формат data-val-rule="Error Message", где правило является именем правила проверки (например data-val-required, , data-val-email, data-val-maxlengthи т. д.). Если в атрибуте указано сообщение об ошибке, оно отображается в качестве значения атрибута data-val-rule . Также существуют атрибуты формы data-val-ruleName-argumentName="argumentValue", которые содержат дополнительные сведения о правиле, например data-val-maxlength-max="1024".
При привязке нескольких input элементов управления к одному свойству созданные элементы управления используют одинаковый id, что делает генерируемую разметку недопустимой. Чтобы предотвратить дубликаты, укажите id атрибут для каждого элемента управления явным образом.
Флажок скрытая отрисовка входных данных
Флажки в HTML5 не передают значение, если они не отмечены. Чтобы включить отправку значения по умолчанию для неснятого флажка, вспомогательная функция тега ввода создает дополнительный скрытый элемент ввода для флажков.
Например, рассмотрим следующую Razor разметку, которая использует вспомогательный модуль тега ввода для логического свойства IsChecked модели:
<form method="post">
<input asp-for="@Model.IsChecked" />
<button type="submit">Submit</button>
</form>
Razor Предыдущая разметка создает разметку HTML, аналогичную следующей:
<form method="post">
<input name="IsChecked" type="checkbox" value="true" />
<button type="submit">Submit</button>
<input name="IsChecked" type="hidden" value="false" />
</form>
В приведенной выше разметке HTML показаны дополнительные скрытые входные данные с именем IsChecked и значением false. По умолчанию этот скрытый вход отображается в конце формы. При отправке формы:
- Если установлен флажок
IsChecked, тоtrueиfalseотправляются как значения. -
IsCheckedЕсли флажок не установлен, отправляется только скрытое входное значениеfalse.
Процесс привязки моделей ASP.NET Core считывает только первое значение при привязке к значению bool, что приводит к true для отмеченных флажков и false для неотмеченных флажков.
Чтобы настроить поведение отрисовки скрытого ввода, установите свойство CheckBoxHiddenInputRenderMode на MvcViewOptions.HtmlHelperOptions. Например:
services.Configure<MvcViewOptions>(options =>
options.HtmlHelperOptions.CheckBoxHiddenInputRenderMode =
CheckBoxHiddenInputRenderMode.None);
Предыдущий код отключает скрытую отрисовку полей ввода для флажков, устанавливая CheckBoxHiddenInputRenderMode в значение CheckBoxHiddenInputRenderMode.None. Информацию о всех доступных режимах отрисовки смотрите в перечислении CheckBoxHiddenInputRenderMode.
Альтернативы вспомогательной функции HTML для вспомогательного элемента ввода
Html.TextBox, Html.TextBoxFor, Html.Editor и Html.EditorFor имеют пересекающиеся функции со вспомогателем ввода. Вспомогательная функция тега входных данных будет автоматически задавать атрибут type, а Html.TextBox и Html.TextBoxFor — нет. Html.EditorFor и Html.TextBoxFor строго типизированы (они используют лямбда-выражения); Html.TextBox и Html.Editor не строго типизированы (они используют имена выражений).
Атрибуты HTML
При выполнении шаблонов по умолчанию @Html.Editor() и @Html.EditorFor() используют специальную запись ViewDataDictionary с именем htmlAttributes. Это поведение может быть дополнительно изменено параметрами additionalViewData. Ключ "htmlAttributes" не чувствителен к регистру. Ключ "htmlAttributes" обрабатывается аналогично объекту htmlAttributes, который передается во вспомогательные функции для работы с вводом, такие как @Html.TextBox().
@Html.EditorFor(model => model.YourProperty,
new { htmlAttributes = new { @class="myCssClass", style="Width:100px" } })
Имена выражений
Значением атрибута asp-for является ModelExpression и правая часть лямбда-выражения. Поэтому в сгенерированном коде asp-for="Property1" становится m => m.Property1, и поэтому не нужно добавлять префикс Model. Чтобы начать встроенное выражение и переместить перед m., используется символ "@":
@{
var joe = "Joe";
}
<input asp-for="@joe">
Выводится следующий результат:
<input type="text" id="joe" name="joe" value="Joe">
При использовании свойств коллекции asp-for="CollectionProperty[23].Member" генерирует то же самое имя, что и asp-for="CollectionProperty[i].Member", если i имеет значение 23.
Когда MVC ASP.NET Core рассчитывает значение ModelExpression, он оценивает несколько источников, включая ModelState. Рассмотрите <input type="text" asp-for="Name">. Рассчитанный атрибут value является первым значением, отличным от NULL, из:
- запись
ModelStateс ключом "Name". - Результат выражения
Model.Name.
Навигация по дочерним свойствам
Для перехода к дочерним свойствам можно также использовать путь к свойству модели представления. Рассмотрим более сложный класс модели, который содержит дочернее свойство Address.
public class AddressViewModel
{
public string AddressLine1 { get; set; }
}
public class RegisterAddressViewModel
{
public string Email { get; set; }
[DataType(DataType.Password)]
public string Password { get; set; }
public AddressViewModel Address { get; set; }
}
В представлении мы привязываем к Address.AddressLine1:
@model RegisterAddressViewModel
<form asp-controller="Demo" asp-action="RegisterAddress" method="post">
<label>Email: <input asp-for="Email" /></label> <br />
<label>Password: <input asp-for="Password" /></label><br />
<label>Address: <input asp-for="Address.AddressLine1" /></label><br />
<button type="submit">Register</button>
</form>
Следующий HTML создан для Address.AddressLine1:
<input type="text" id="Address_AddressLine1" name="Address.AddressLine1" value="">
Имена выражений и коллекций
Пример модели, содержащей массив Colors:
public class Person
{
public List<string> Colors { get; set; }
public int Age { get; set; }
}
Метод действия:
public IActionResult Edit(int id, int colorIndex)
{
ViewData["Index"] = colorIndex;
return View(GetPerson(id));
}
Razor Ниже показано, как получить доступ к конкретному Color элементу:
@model Person
@{
var index = (int)ViewData["index"];
}
<form asp-controller="ToDo" asp-action="Edit" method="post">
@Html.EditorFor(m => m.Colors[index])
<label asp-for="Age"></label>
<input asp-for="Age" /><br />
<button type="submit">Post</button>
</form>
Шаблон Views/Shared/EditorTemplates/String.cshtml :
@model string
<label asp-for="@Model"></label>
<input asp-for="@Model" /> <br />
Пример с использованием List<T>:
public class ToDoItem
{
public string Name { get; set; }
public bool IsDone { get; set; }
}
Razor Ниже показано, как выполнить итерацию по коллекции:
@model List<ToDoItem>
<form asp-controller="ToDo" asp-action="Edit" method="post">
<table>
<tr> <th>Name</th> <th>Is Done</th> </tr>
@for (int i = 0; i < Model.Count; i++)
{
<tr>
@Html.EditorFor(model => model[i])
</tr>
}
</table>
<button type="submit">Save</button>
</form>
Шаблон Views/Shared/EditorTemplates/ToDoItem.cshtml :
@model ToDoItem
<td>
<label asp-for="@Model.Name"></label>
@Html.DisplayFor(model => model.Name)
</td>
<td>
<input asp-for="@Model.IsDone" />
</td>
@*
This template replaces the following Razor which evaluates the indexer three times.
<td>
<label asp-for="@Model[i].Name"></label>
@Html.DisplayFor(model => model[i].Name)
</td>
<td>
<input asp-for="@Model[i].IsDone" />
</td>
*@
По возможности следует использовать foreach, когда значение будет применяться в эквивалентном контексте asp-for или Html.DisplayFor. Обычно лучше использовать for, чем foreach (если сценарий позволяет), так как ему не нужно выделять перечислитель. Тем не менее оценка индексатора в выражении LINQ может быть недешевой, поэтому ее нужно минимизировать.
Примечание.
В приведенном выше комментированном коде показано, как заменить лямбда-выражение оператором @, чтобы получить доступ к каждому ToDoItem в списке.
Вспомогательная функция тега Textarea
Вспомогательная функция тега Textarea Tag Helperаналогична вспомогательной функции тега входных данных.
Предлагается создание атрибутов
id, а также атрибутов проверки данныхnameиз модели для элемента <textarea>.Обеспечивает строгую типизацию.
Альтернатива HTML Helper:
Html.TextAreaFor.
Пример:
using System.ComponentModel.DataAnnotations;
namespace FormsTagHelper.ViewModels
{
public class DescriptionViewModel
{
[MinLength(5)]
[MaxLength(1024)]
public string Description { get; set; }
}
}
@model DescriptionViewModel
<form asp-controller="Demo" asp-action="RegisterTextArea" method="post">
<textarea asp-for="Description"></textarea>
<button type="submit">Test</button>
</form>
Создается следующий HTML:
<form method="post" action="/Demo/RegisterTextArea">
<textarea data-val="true"
data-val-maxlength="The field Description must be a string or array type with a maximum length of '1024'."
data-val-maxlength-max="1024"
data-val-minlength="The field Description must be a string or array type with a minimum length of '5'."
data-val-minlength-min="5"
id="Description" name="Description">
</textarea>
<button type="submit">Test</button>
<input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>
Вспомогательная функция тега метки
Создает подпись
forи атрибут метки в элементе <метки> для имени выражения.Альтернатива помощнику HTML:
Html.LabelFor.
Элемент Label Tag Helper предоставляет следующие преимущества по сравнению с чистым элементом метки HTML:
Вы автоматически получаете значение описательной метки из
Displayатрибута. Предполагаемое отображаемое имя может изменяться с течением времени, а сочетание атрибутаDisplayи вспомогательной функции тега метки будет применять атрибутDisplayвезде, где он используется.Меньше разметки в исходном коде.
Строгая типизация со свойством модели.
Пример:
using System.ComponentModel.DataAnnotations;
namespace FormsTagHelper.ViewModels
{
public class SimpleViewModel
{
[Required]
[EmailAddress]
[Display(Name = "Email Address")]
public string Email { get; set; }
}
}
@model SimpleViewModel
<form asp-controller="Demo" asp-action="RegisterLabel" method="post">
<label asp-for="Email"></label>
<input asp-for="Email" /> <br />
</form>
Для элемента <label> создан следующий HTML:
<label for="Email">Email Address</label>
Вспомогательная функция тега метки сгенерировала для атрибута for значение "Email", представляющее собой идентификатор, связанный с элементом <input>. Вспомогательные функции тегов создают согласованные элементы id и for, чтобы обеспечить их правильное связывание. Заголовок в этом примере взят из атрибута Display. Если модель не содержит атрибут Display, заголовком будет имя свойства выражения. Чтобы переопределить подпись по умолчанию, добавьте подпись внутри тега метки.
Вспомогательные теги валидации
Существует две вспомогательные функции тегов проверки.
Validation Message Tag Helper отображает сообщение проверки для одного свойства в модели, Validation Summary Tag Helper отображает сводку ошибок проверки.
Input Tag Helper добавляет атрибуты валидации на стороне клиента HTML5 для элементов ввода на основе атрибутов аннотации данных в классах модели. Проверка также выполняется на сервере. Вспомогательная функция тега проверки отображает эти сообщения об ошибках при возникновении ошибки проверки.
Вспомогательная функция тега сообщения о проверке
Добавляет атрибут HTML5 в элемент span, который присоединяет сообщения об ошибках проверки к полю ввода данных указанного свойства модели. При возникновении ошибки проверки на стороне клиента jQuery отображает сообщение об ошибке в элементе
<span>.Проверка также выполняется на сервере. Клиенты могут отключить JavaScript и выполнить проверку можно только на стороне сервера.
Альтернатива помощнику HTML:
Html.ValidationMessageFor.
Элемент span HTML используется с атрибутом asp-validation-for и Validation Message Tag Helper.
<span asp-validation-for="Email"></span>
Вспомогательная функция тега сообщения о проверке создает следующий HTML:
<span class="field-validation-valid"
data-valmsg-for="Email"
data-valmsg-replace="true"></span>
Как правило, вы используете Validation Message Tag Helper после вспомогательного Input тега для того же свойства. В этом случае сообщения об ошибках проверки отображаются рядом с входными данными, вызвавшими ошибку.
Примечание.
Для проверки на стороне клиента необходимо иметь представление с правильными ссылками на скрипты JavaScript и jQuery. Дополнительные сведения см. в разделе "Проверка модели".
При возникновении ошибки проверки на стороне сервера (например, если выполняется пользовательская проверка на стороне сервера или проверка на стороне клиент отключена) MVC размещает сообщение об ошибке в тексте элемента <span>.
<span class="field-validation-error" data-valmsg-for="Email"
data-valmsg-replace="true">
The Email Address field is required.
</span>
Вспомогательная функция тега сводки по проверке
Нацеливает
<div>элементы с атрибутомasp-validation-summary.Альтернатива HTML Helper:
@Html.ValidationSummary.
Используется Validation Summary Tag Helper для отображения сводки сообщений проверки. Значением атрибута asp-validation-summary может быть любое из следующих:
| asp-validation-summary | Отображаемые сообщения о проверке |
|---|---|
All |
Свойство и уровень модели |
ModelOnly |
Модель |
None |
нет |
Пример
В следующем примере модель данных имеет атрибуты DataAnnotation, в результате чего создаются сообщения об ошибках проверки для элемента <input>. При возникновении ошибки проверки вспомогательная функция тега проверки отображает следующее сообщение об ошибке:
using System.ComponentModel.DataAnnotations;
namespace FormsTagHelper.ViewModels
{
public class RegisterViewModel
{
[Required]
[EmailAddress]
[Display(Name = "Email Address")]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
}
}
@model RegisterViewModel
<form asp-controller="Demo" asp-action="RegisterValidation" method="post">
<div asp-validation-summary="ModelOnly"></div>
<label>Email: <input asp-for="Email" /></label> <br />
<span asp-validation-for="Email"></span><br />
<label>Password: <input asp-for="Password" /></label><br />
<span asp-validation-for="Password"></span><br />
<button type="submit">Register</button>
</form>
Созданный HTML (если модель является допустимой):
<form action="/DemoReg/Register" method="post">
<label>Email: <input name="Email" id="Email" type="email" value=""
data-val-required="The Email field is required."
data-val-email="The Email field is not a valid email address."
data-val="true"></label><br>
<span class="field-validation-valid" data-valmsg-replace="true"
data-valmsg-for="Email"></span><br>
<label>Password: <input name="Password" id="Password" type="password"
data-val-required="The Password field is required." data-val="true"></label><br>
<span class="field-validation-valid" data-valmsg-replace="true"
data-valmsg-for="Password"></span><br>
<button type="submit">Register</button>
<input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>
Вспомогательная функция тега Select
Создает элементы select и соответствующие элементы option для свойств вашей модели.
Существует альтернатива для HTML-помощника
Html.DropDownListForиHtml.ListBoxFor.
Select Tag Helper
asp-for указывает имя свойства модели для элемента select, а asp-items указывает элементы option. Например:
<select asp-for="Country" asp-items="Model.Countries"></select>
Пример:
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Collections.Generic;
namespace FormsTagHelper.ViewModels
{
public class CountryViewModel
{
public string Country { get; set; }
public List<SelectListItem> Countries { get; } = new List<SelectListItem>
{
new SelectListItem { Value = "MX", Text = "Mexico" },
new SelectListItem { Value = "CA", Text = "Canada" },
new SelectListItem { Value = "US", Text = "USA" },
};
}
}
Метод Index инициализирует CountryViewModel объект, задает выбранную страну и передает её в Index представление.
public IActionResult Index()
{
var model = new CountryViewModel();
model.Country = "CA";
return View(model);
}
Метод HTTP POST Index отображает выбор:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Index(CountryViewModel model)
{
if (ModelState.IsValid)
{
var msg = model.Country + " selected";
return RedirectToAction("IndexSuccess", new { message = msg });
}
// If we got this far, something failed; redisplay form.
return View(model);
}
Представление Index:
@model CountryViewModel
<form asp-controller="Home" asp-action="Index" method="post">
<select asp-for="Country" asp-items="Model.Countries"></select>
<br /><button type="submit">Register</button>
</form>
Создается следующий HTML (с выбранным значением "CA"):
<form method="post" action="/">
<select id="Country" name="Country">
<option value="MX">Mexico</option>
<option selected="selected" value="CA">Canada</option>
<option value="US">USA</option>
</select>
<br /><button type="submit">Register</button>
<input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>
Примечание.
С вспомогательной функцией тега Select не рекомендуется использовать ViewBag или ViewData. Модель представления более надежна при предоставлении метаданных MVC и менее проблемной.
Значение атрибута asp-for является особым случаем и не требует префикса Model. Другие вспомогательные атрибуты тегов действуют (например, asp-items).
<select asp-for="Country" asp-items="Model.Countries"></select>
Привязка перечисления
Часто бывает удобно использовать <select> со свойством enum и создавать элементы SelectListItem из значений enum.
Пример:
public class CountryEnumViewModel
{
public CountryEnum EnumCountry { get; set; }
}
using System.ComponentModel.DataAnnotations;
namespace FormsTagHelper.ViewModels
{
public enum CountryEnum
{
[Display(Name = "United Mexican States")]
Mexico,
[Display(Name = "United States of America")]
USA,
Canada,
France,
Germany,
Spain
}
}
Метод GetEnumSelectList создает объект SelectList для перечисления.
@model CountryEnumViewModel
<form asp-controller="Home" asp-action="IndexEnum" method="post">
<select asp-for="EnumCountry"
asp-items="Html.GetEnumSelectList<CountryEnum>()">
</select>
<br /><button type="submit">Register</button>
</form>
Список перечислителя можно пометить атрибутом Display для формирования пользовательского интерфейса с более широкими функциональными возможностями:
using System.ComponentModel.DataAnnotations;
namespace FormsTagHelper.ViewModels
{
public enum CountryEnum
{
[Display(Name = "United Mexican States")]
Mexico,
[Display(Name = "United States of America")]
USA,
Canada,
France,
Germany,
Spain
}
}
Создается следующий HTML:
<form method="post" action="/Home/IndexEnum">
<select data-val="true" data-val-required="The EnumCountry field is required."
id="EnumCountry" name="EnumCountry">
<option value="0">United Mexican States</option>
<option value="1">United States of America</option>
<option value="2">Canada</option>
<option value="3">France</option>
<option value="4">Germany</option>
<option selected="selected" value="5">Spain</option>
</select>
<br /><button type="submit">Register</button>
<input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>
Группа опций
Элемент html <optgroup> создается, когда модель представления содержит один или несколько SelectListGroup объектов.
CountryViewModelGroup группирует элементы SelectListItem в группы "North America" и "Europe":
public class CountryViewModelGroup
{
public CountryViewModelGroup()
{
var NorthAmericaGroup = new SelectListGroup { Name = "North America" };
var EuropeGroup = new SelectListGroup { Name = "Europe" };
Countries = new List<SelectListItem>
{
new SelectListItem
{
Value = "MEX",
Text = "Mexico",
Group = NorthAmericaGroup
},
new SelectListItem
{
Value = "CAN",
Text = "Canada",
Group = NorthAmericaGroup
},
new SelectListItem
{
Value = "US",
Text = "USA",
Group = NorthAmericaGroup
},
new SelectListItem
{
Value = "FR",
Text = "France",
Group = EuropeGroup
},
new SelectListItem
{
Value = "ES",
Text = "Spain",
Group = EuropeGroup
},
new SelectListItem
{
Value = "DE",
Text = "Germany",
Group = EuropeGroup
}
};
}
public string Country { get; set; }
public List<SelectListItem> Countries { get; }
Две группы показаны следующим образом:
Созданный HTML:
<form method="post" action="/Home/IndexGroup">
<select id="Country" name="Country">
<optgroup label="North America">
<option value="MEX">Mexico</option>
<option value="CAN">Canada</option>
<option value="US">USA</option>
</optgroup>
<optgroup label="Europe">
<option value="FR">France</option>
<option value="ES">Spain</option>
<option value="DE">Germany</option>
</optgroup>
</select>
<br /><button type="submit">Register</button>
<input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>
Множественный выбор
Вспомогательная функция Select автоматически создаст атрибут multiple = "multiple", если свойство, указанное в атрибуте asp-for, имеет значение IEnumerable. Допустим, имеется такая модель:
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Collections.Generic;
namespace FormsTagHelper.ViewModels
{
public class CountryViewModelIEnumerable
{
public IEnumerable<string> CountryCodes { get; set; }
public List<SelectListItem> Countries { get; } = new List<SelectListItem>
{
new SelectListItem { Value = "MX", Text = "Mexico" },
new SelectListItem { Value = "CA", Text = "Canada" },
new SelectListItem { Value = "US", Text = "USA" },
new SelectListItem { Value = "FR", Text = "France" },
new SelectListItem { Value = "ES", Text = "Spain" },
new SelectListItem { Value = "DE", Text = "Germany"}
};
}
}
Со следующим представлением:
@model CountryViewModelIEnumerable
<form asp-controller="Home" asp-action="IndexMultiSelect" method="post">
<select asp-for="CountryCodes" asp-items="Model.Countries"></select>
<br /><button type="submit">Register</button>
</form>
Генерирует следующий HTML:
<form method="post" action="/Home/IndexMultiSelect">
<select id="CountryCodes"
multiple="multiple"
name="CountryCodes"><option value="MX">Mexico</option>
<option value="CA">Canada</option>
<option value="US">USA</option>
<option value="FR">France</option>
<option value="ES">Spain</option>
<option value="DE">Germany</option>
</select>
<br /><button type="submit">Register</button>
<input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>
Нет выбранных элементов
Если вы используете параметр "not specified" (не выбрано) на нескольких страницах, можно создать шаблон, чтобы исключить повторяющийся HTML:
@model CountryViewModel
<form asp-controller="Home" asp-action="IndexEmpty" method="post">
@Html.EditorForModel()
<br /><button type="submit">Register</button>
</form>
Шаблон Views/Shared/EditorTemplates/CountryViewModel.cshtml :
@model CountryViewModel
<select asp-for="Country" asp-items="Model.Countries">
<option value="">--none--</option>
</select>
Добавление HTML-элементов
public IActionResult IndexNone()
{
var model = new CountryViewModel();
model.Countries.Insert(0, new SelectListItem("<none>", ""));
return View(model);
}
@model CountryViewModel
<form asp-controller="Home" asp-action="IndexEmpty" method="post">
<select asp-for="Country">
<option value=""><none></option>
<option value="MX">Mexico</option>
<option value="CA">Canada</option>
<option value="US">USA</option>
</select>
<br /><button type="submit">Register</button>
</form>
Правильный элемент <option> (содержит атрибут selected="selected") будет выбран в зависимости от текущего значения Country.
public IActionResult IndexOption(int id)
{
var model = new CountryViewModel();
model.Country = "CA";
return View(model);
}
<form method="post" action="/Home/IndexEmpty">
<select id="Country" name="Country">
<option value=""><none></option>
<option value="MX">Mexico</option>
<option value="CA" selected="selected">Canada</option>
<option value="US">USA</option>
</select>
<br /><button type="submit">Register</button>
<input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>
Дополнительные ресурсы
ASP.NET Core