Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
De Rick Anderson, N. Taylor Mullen, Dave Paquette e Jerrie Pelser
Este documento demonstra como é o trabalho com Formulários e os elementos HTML usados comumente em um Formulário. O elemento HTML Formulário fornece o mecanismo primário que os aplicativos Web usam para postar dados para o servidor. A maior parte deste documento descreve os Tag Helpers e como eles podem ajudá-lo a criar formulários HTML robustos de maneira produtiva. É recomendável que você leia Introdução aos Tag Helpers antes de ler este documento.
Em muitos casos, os Auxiliares HTML oferecem uma abordagem alternativa a um Auxiliar de Marca específico. No entanto, é importante reconhecer que os Auxiliares de Marca não substituem auxiliares HTML e não há um Auxiliar de Marca para cada auxiliar HTML. Quando existe um Auxiliar HTML alternativo, ele é mencionado.
O Auxiliar de marca de formulário
O Auxiliar de Marca de Formulário:
Gera o valor do atributo HTML <FORM>
actionpara uma ação do controlador MVC ou uma rota nomeada.Gera um Token de Verificação de Solicitação oculto para impedir a falsificação de solicitação entre sites (quando usado com o
[ValidateAntiForgeryToken]atributo no método de ação HTTP Post).Fornece o atributo
asp-route-<Parameter Name>, em que<Parameter Name>é adicionado aos valores de rota. Os parâmetrosrouteValuesparaHtml.BeginFormeHtml.BeginRouteFormfornecem funcionalidade semelhante.Há uma alternativa de Helper HTML
Html.BeginFormeHtml.BeginRouteForm.
Exemplo:
<form asp-controller="Demo" asp-action="Register" method="post">
<!-- Input and Submit elements -->
</form>
O Auxiliar de Marca de Formulário anterior gera o seguinte código HTML:
<form method="post" action="/Demo/Register">
<!-- Input and Submit elements -->
<input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>
O tempo de execução do MVC gera o valor do atributo action a partir dos atributos asp-controller e asp-action do Form Tag Helper. O Auxiliar de marca de formulário também gera um Token de verificação de solicitação oculto para evitar a falsificação de solicitações entre sites (quando usado com o atributo [ValidateAntiForgeryToken] no método de ação HTTP Post). Proteger um formulário HTML puro contra falsificação de solicitação entre sites é difícil, mas o Auxiliar de Marca de Formulário oferece esse recurso para você.
Usando uma rota nomeada
O atributo do Tag Helper asp-route também pode gerar a marcação para o atributo HTML action. Um aplicativo com uma rota chamada register poderia usar a seguinte marcação para a página de registro:
<form asp-route="register" method="post">
<!-- Input and Submit elements -->
</form>
Muitas das exibições na pasta Views/Account (geradas quando você cria um novo aplicativo Web com contas individuais) contêm o atributo asp-route-returnurl :
<form asp-controller="Account" asp-action="Login"
asp-route-returnurl="@ViewData["ReturnUrl"]"
method="post" class="form-horizontal" role="form">
Observação
Com os modelos integrados, returnUrl só é preenchido automaticamente quando você tenta acessar um recurso autorizado, mas não está autenticado ou autorizado. Quando você tenta fazer um acesso não autorizado, o middleware de segurança o redireciona para a página de logon com o returnUrl definido.
Auxiliar de Marcação de Ação de Formulário
O Auxiliar de Marcação de Ação de Formulário gera o atributo formaction na marcação <button ...> ou <input type="image" ...> gerada. O atributo formaction controla onde um formulário envia seus dados. Ele se vincula a <entrada> elementos de tipo image e <elementos> de botão. O Auxiliar de marca de Ação do Formulário permite o uso de vários atributos AnchorTagHelperasp- para controlar qual link formaction é gerado para o elemento correspondente.
Atributos AnchorTagHelper com suporte para controlar o valor de formaction:
| Atributo | Descrição |
|---|---|
| asp-controller | O nome do controlador. |
| asp-action | O nome do método da ação. |
| asp-area | O nome da área. |
| asp-page | O nome da página Razor. |
| asp-page-handler | O nome do manipulador da página Razor. |
| asp-route | O nome da rota. |
| asp-route-{value} | Um único valor de rota de URL. Por exemplo, asp-route-id="1234". |
| asp-all-route-data | Todos os valores de rota. |
| asp-fragment | O fragmento de URL. |
Exemplo de Enviar ao controlador
A marcação a seguir envia o formulário para a ação Index de HomeController quando o campo de entrada ou o botão for selecionado:
<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>
A marcação anterior gera o seguinte HTML:
<form method="post">
<button formaction="/Home">Click Me</button>
<input type="image" src="..." alt="Or Click Me" formaction="/Home">
</form>
Submeter para exemplo de página
A marcação a seguir envia o formulário para a Página AboutRazor:
<form method="post">
<button asp-page="About">Click Me</button>
<input type="image" src="..." alt="Or Click Me" asp-page="About">
</form>
A marcação anterior gera o seguinte HTML:
<form method="post">
<button formaction="/About">Click Me</button>
<input type="image" src="..." alt="Or Click Me" formaction="/About">
</form>
Exemplo de Enviar a uma rota
Considere o ponto de extremidade /Home/Test:
public class HomeController : Controller
{
[Route("/Home/Test", Name = "Custom")]
public string Test()
{
return "This is the test page";
}
}
A seguinte marcação envia o formulário ao endpoint /Home/Test.
<form method="post">
<button asp-route="Custom">Click Me</button>
<input type="image" src="..." alt="Or Click Me" asp-route="Custom">
</form>
A marcação anterior gera o seguinte HTML:
<form method="post">
<button formaction="/Home/Test">Click Me</button>
<input type="image" src="..." alt="Or Click Me" formaction="/Home/Test">
</form>
O auxiliar de marca de entrada
O Auxiliar de marca de <entrada> associa um elemento de entrada do HTML a uma expressão de modelo em seu modo de exibição do Razor.
Sintaxe:
<input asp-for="<Expression Name>">
O auxiliar de marca de entrada:
Gera os atributos HTML
idenamepara o nome da expressão especificada no atributoasp-for.asp-for="Property1.Property2"é equivalente am => m.Property1.Property2. O nome da expressão é o que é usado para o valor do atributoasp-for. Para obter mais informações, consulte a seção Nomes de expressão .Define o valor do atributo HTML
typecom base no tipo de modelo e atributos de anotação de dados aplicados à propriedade do modelo.Não substituirá o valor do atributo HTML
typequando especificado.Gera atributos de validação HTML5 a partir de atributos de anotação de dados aplicados às propriedades do modelo.
Tem uma sobreposição de recursos de Auxiliar HTML com
Html.TextBoxForeHtml.EditorFor. Consulte a seção Alternativas de Auxiliar HTML ao Auxiliar de marca de entrada para obter detalhes.Fornece tipagem forte. Se o nome da propriedade for alterado e você não atualizar o Tag Helper, receberá um erro semelhante ao seguinte:
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?)
O Auxiliar de marca Input define o atributo HTML type com base no tipo .NET. A tabela a seguir lista alguns tipos .NET comuns e o tipo HTML gerado (não estão listados todos os tipos .NET).
| Tipo .NET | Tipo de entrada |
|---|---|
| Bool | type="checkbox" |
| fio | type="text" |
| Data e Hora | type="datetime-local" |
| Byte | type="number" |
| int | type="number" |
| Single e Double | type="number" |
A tabela a seguir mostra alguns atributos de anotações de dados comuns que o auxiliar de marca de entrada mapeará para tipos de entrada específicos (não são listados todos os atributos de validação):
| Atributo | Tipo de entrada |
|---|---|
| [EmailAddress] | type="email" |
| [URL] | type="url" |
| [HiddenInput] | type="hidden" |
| [Phone] | type="tel" |
| [DataType(DataType.Password)] | type="password" |
| [DataType(DataType.Date)] | type="date" |
| [DataType(DataType.Time)] | type="hora" |
Exemplo:
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>
O código anterior gera o seguinte 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>
As anotações de dados aplicadas às propriedades Email e Password geram metadados no modelo. O Auxiliar de Marca de Entrada consome os metadados do modelo e produz atributos HTML5data-val-* (veja Validação de Modelo). Esses atributos descrevem os validadores a serem anexados aos campos de entrada. Isso fornece validação discreta de HTML5 e jQuery. Os atributos discretos têm o formato data-val-rule="Error Message", em que a regra é o nome da regra de validação (como data-val-required, , data-val-email, data-val-maxlengthetc.). Se uma mensagem de erro for fornecida no atributo, ela será exibida como o valor do data-val-rule atributo. Também há atributos do formulário data-val-ruleName-argumentName="argumentValue" que fornecem detalhes adicionais sobre a regra, por exemplo, data-val-maxlength-max="1024".
Ao associar vários controles do input à mesma propriedade, os controles gerados compartilham o mesmo id, o que torna a marcação gerada inválida. Para evitar duplicatas, especifique o atributo id para cada controle explicitamente.
Renderização de entrada oculta da caixa de seleção
As caixas de seleção em HTML5 não enviam um valor quando estão desmarcadas. Para habilitar um valor padrão a ser enviado para uma caixa de seleção desmarcada, o Input Tag Helper gera uma entrada oculta adicional para checkboxes.
Por exemplo, considere a marcação Razor a seguir que usa o Input Tag Helper para uma propriedade de modelo booleano IsChecked:
<form method="post">
<input asp-for="@Model.IsChecked" />
<button type="submit">Submit</button>
</form>
A marcação Razor anterior gera marcação HTML semelhante à seguinte:
<form method="post">
<input name="IsChecked" type="checkbox" value="true" />
<button type="submit">Submit</button>
<input name="IsChecked" type="hidden" value="false" />
</form>
A marcação HTML anterior mostra uma entrada oculta adicional com um nome de IsChecked e um valor de false. Por padrão, essa entrada oculta é renderizada no final do formulário. Quando o formulário é enviado:
- Se a entrada da
IsCheckedcaixa de seleção for marcada,trueefalseserão enviadas como valores. - Se a entrada da caixa de seleção
IsCheckedestiver desmarcada, somente o valorfalsede entrada oculto será enviado.
O processo de associação de modelo do ASP.NET Core lê apenas o primeiro valor ao associar a um valor bool, o que resulta em true para caixas de seleção marcadas e false para caixas de seleção desmarcadas.
Para configurar o comportamento da renderização de entrada oculta, defina a propriedade CheckBoxHiddenInputRenderMode em MvcViewOptions.HtmlHelperOptions. Por exemplo:
services.Configure<MvcViewOptions>(options =>
options.HtmlHelperOptions.CheckBoxHiddenInputRenderMode =
CheckBoxHiddenInputRenderMode.None);
O código anterior desabilita a renderização de entrada oculta para caixas de seleção definindo CheckBoxHiddenInputRenderMode como CheckBoxHiddenInputRenderMode.None. Para todos os modos de renderização disponíveis, consulte a enumeração CheckBoxHiddenInputRenderMode.
Alternativas de Auxiliar HTML ao Auxiliar de marca de entrada
Html.TextBox, Html.TextBoxFor, Html.Editor, e Html.EditorFor têm funcionalidades em comum com o Auxiliar de Marca de Entrada. O Tag Helper de entrada definirá automaticamente o atributo type; Html.TextBox e Html.TextBoxFor não farão isso.
Html.Editor e Html.EditorFor manipulam coleções, objetos complexos e templates; o Auxiliar de Marca de Entrada não. Os Auxiliares de Marca de Entrada, Html.EditorFor, e Html.TextBoxFor são fortemente tipados (utilizam expressões lambda); Html.TextBox e não Html.Editor (utilizam nomes de expressões).
Atributos HTML
@Html.Editor() e @Html.EditorFor() usam uma entrada ViewDataDictionary especial chamada htmlAttributes ao executar seus modelos padrão. Esse comportamento pode ser aumentado usando parâmetros additionalViewData. A chave "htmlAttributes" não diferencia maiúsculas de minúsculas. A chave "htmlAttributes" é tratada de forma semelhante ao objeto htmlAttributes passado para auxiliares de entrada como @Html.TextBox().
@Html.EditorFor(model => model.YourProperty,
new { htmlAttributes = new { @class="myCssClass", style="Width:100px" } })
Nomes de expressão
O valor do atributo asp-for é um ModelExpression e o lado direito de uma expressão lambda. Portanto, asp-for="Property1" torna-se m => m.Property1 no código gerado, e é por isso que você não precisa prefixar com Model. Você pode usar o caractere "@" para iniciar uma expressão embutida e mover para antes de m.:
@{
var joe = "Joe";
}
<input asp-for="@joe">
Gera o seguinte:
<input type="text" id="joe" name="joe" value="Joe">
Com propriedades de coleção, asp-for="CollectionProperty[23].Member" gera o mesmo nome que asp-for="CollectionProperty[i].Member" quando i tem o valor 23.
Quando o ASP.NET Core MVC calcula o valor de ModelExpression, ele inspeciona várias fontes, inclusive o ModelState. Considere o <input type="text" asp-for="Name">. O atributo value calculado é o primeiro valor não nulo:
-
ModelStateentrada com a chave "Nome". - Resultado da expressão
Model.Name.
Navegando para propriedades filho
Você também pode navegar para propriedades filho usando o caminho da propriedade do modelo de exibição. Considere uma classe de modelo mais complexa que contém uma propriedade Address filho.
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; }
}
Na visualização, vinculamos a 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>
O HTML a seguir é gerado para Address.AddressLine1:
<input type="text" id="Address_AddressLine1" name="Address.AddressLine1" value="">
Nomes de expressão e coleções
Exemplo, um modelo que contém uma matriz de Colors:
public class Person
{
public List<string> Colors { get; set; }
public int Age { get; set; }
}
O método de ação:
public IActionResult Edit(int id, int colorIndex)
{
ViewData["Index"] = colorIndex;
return View(GetPerson(id));
}
O Razor a seguir mostra como você acessa um elemento Color específico:
@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>
O modelo Views/Shared/EditorTemplates/String.cshtml:
@model string
<label asp-for="@Model"></label>
<input asp-for="@Model" /> <br />
Exemplo usando List<T>:
public class ToDoItem
{
public string Name { get; set; }
public bool IsDone { get; set; }
}
O Razor a seguir mostra como iterar em uma coleção:
@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>
O modelo 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 deve ser usado, se possível, quando o valor está prestes a ser usado em um contexto equivalente asp-for ou Html.DisplayFor. Em geral, for é melhor do que foreach (se o cenário permitir) porque não é necessário alocar um enumerador; no entanto, avaliar um indexador em uma expressão LINQ pode ser caro, o que deve ser minimizado.
Observação
O código de exemplo comentado acima mostra como você substituiria a expressão lambda pelo operador @ para acessar cada ToDoItem na lista.
Auxiliar de marca de área de texto
O tag helper Textarea Tag Helper é semelhante ao Input Tag Helper.
Gera os atributos
idename, bem como os atributos de validação de dados do modelo para um elemento <textarea>.Fornece tipagem forte.
Auxiliar HTML Alternativo:
Html.TextAreaFor.
Exemplo:
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>
O HTML a seguir é gerado:
<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>
O auxiliar de marca de rótulo
Gera o texto e o atributo
forde um elemento de <rótulo> para um nome de expressão.Alternativa para Assistente HTML:
Html.LabelFor.
O Label Tag Helper fornece os seguintes benefícios em comparação com um elemento de rótulo HTML puro:
Você obtém automaticamente o valor da etiqueta descritiva do atributo
Display. O nome de exibição desejado pode mudar com o tempo e a combinação do atributoDisplaye do Auxiliar de Marca de Rótulo aplicaráDisplayem qualquer lugar em que for usado.Menos marcação no código-fonte.
Tipagem forte com a propriedade de modelo.
Exemplo:
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>
O HTML a seguir é gerado para o elemento <label>:
<label for="Email">Email Address</label>
O Label Tag Helper gerou o valor do atributo for como "Email", que é o ID associado ao elemento <input>. Auxiliares de marca geram elementos id e for consistentes para que eles possam ser associados corretamente. A legenda neste exemplo é proveniente do atributo Display. Se o modelo não contivesse um atributo Display, a legenda seria o nome da propriedade da expressão. Para substituir a legenda padrão, adicione uma legenda dentro da etiqueta label.
Os auxiliares de marca de validação
Há dois auxiliares de marca de validação. O Validation Message Tag Helper (que exibe uma mensagem de validação para uma única propriedade em seu modelo) e o Validation Summary Tag Helper (que exibe um resumo dos erros de validação). O Input Tag Helper adiciona atributos de validação do lado do cliente em HTML5 aos elementos de entrada, baseando-se nos atributos de anotação de dados das suas classes de modelo. A validação também é executada no servidor. O Auxiliar de marca de validação exibe essas mensagens de erro quando ocorre um erro de validação.
O Auxiliar de marca de mensagem de validação
Adiciona o atributo HTML5
data-valmsg-for="property"ao elemento span, que anexa as mensagens de erro de validação ao campo de entrada da propriedade de modelo especificada. Quando ocorre um erro de validação do lado do cliente, jQuery exibe a mensagem de erro no elemento<span>.A validação também é feita no servidor. Os clientes podem ter o JavaScript desabilitado e alguma validação só pode ser feita no lado do servidor.
Alternativa de Helper HTML:
Html.ValidationMessageFor.
O Validation Message Tag Helper é usado com o atributo asp-validation-for em um elemento HTML span.
<span asp-validation-for="Email"></span>
O Tag Helper de mensagem de validação gerará o seguinte HTML:
<span class="field-validation-valid"
data-valmsg-for="Email"
data-valmsg-replace="true"></span>
Geralmente, você usa o Validation Message Tag Helper após um Auxiliar de Marca Input para a mesma propriedade. Fazer isso exibe as mensagens de erro de validação próximo à entrada que causou o erro.
Observação
É necessário ter uma exibição com as referências de script jQuery e JavaScript corretas em vigor para a validação do lado do cliente. Para obter mais informações, consulte Validação de Modelo.
Quando ocorre um erro de validação do lado do servidor (por exemplo, quando você tem validação do lado do servidor personalizada ou a validação do lado do cliente está desabilitada), o MVC coloca essa mensagem de erro como o corpo do elemento <span>.
<span class="field-validation-error" data-valmsg-for="Email"
data-valmsg-replace="true">
The Email Address field is required.
</span>
Auxiliar de marca de resumo de validação
Direciona elementos
<div>com atributoasp-validation-summary.Alternativa de Helper HTML:
@Html.ValidationSummary.
O Validation Summary Tag Helper é usado para exibir um resumo das mensagens de validação. O valor do atributo asp-validation-summary pode ser qualquer um dos seguintes:
| Resumo de Validação do ASP | Mensagens de validação exibidas |
|---|---|
All |
Nível da propriedade e do modelo |
ModelOnly |
Modelo |
None |
Nenhum |
Amostra
No exemplo a seguir, o modelo de dados é decorado com atributos DataAnnotation, o que gera mensagens de erro de validação no elemento <input>. Quando ocorre um erro de validação, o Auxiliar de marca de validação exibe a mensagem de erro:
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>
O código HTML gerado (quando o modelo é válido):
<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>
Auxiliar de Marca de Seleção
Gera select e os elementos option associados para as propriedades do modelo.
Há uma alternativa de Helper HTML
Html.DropDownListForeHtml.ListBoxFor.
O atributo Select Tag Helperasp-for especifica o nome da propriedade do modelo para o elemento selecionar e asp-items especifica os elementos opção. Por exemplo:
<select asp-for="Country" asp-items="Model.Countries"></select>
Exemplo:
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" },
};
}
}
O método Index inicializa o CountryViewModel, define o país selecionado e o passa para a visualização Index.
public IActionResult Index()
{
var model = new CountryViewModel();
model.Country = "CA";
return View(model);
}
O método Index HTTP POST exibe a seleção:
[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);
}
A exibição 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>
Que gera o seguinte HTML (com "CA" selecionado):
<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>
Observação
Não é recomendável usar ViewBag ou ViewData com o Select Tag Helper. Um modelo de exibição é mais robusto no fornecimento de metadados MVC e menos problemático.
O asp-for valor do atributo é um caso especial e não requer um Model prefixo. Os outros atributos dos Tag Helpers funcionam (como asp-items).
<select asp-for="Country" asp-items="Model.Countries"></select>
Associação de enumeração
Geralmente, é conveniente usar <select> com uma propriedade enum e gerar os elementos SelectListItem dos valores enum.
Exemplo:
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
}
}
O método GetEnumSelectList gera um objeto SelectList para uma enumeração.
@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>
É possível decorar sua lista de enumeradores com o atributo Display para obter uma interface do usuário mais rica:
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
}
}
O HTML a seguir é gerado:
<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>
Grupo de opções
O elemento HTML <optgroup> é gerado quando o modelo de exibição contém um ou mais objetos SelectListGroup.
O CountryViewModelGroup agrupa os elementos SelectListItem nos grupos "América do Norte" e "Europa":
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; }
Os dois grupos são mostrados da seguinte maneira:
O HTML gerado:
<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>
Seleção múltipla
O Auxiliar de Marca de Seleção gerará automaticamente o atributo multiple = "multiple" se a propriedade especificada no atributo asp-for for um IEnumerable. Por exemplo, considerando o seguinte modelo:
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"}
};
}
}
Com a seguinte visualização:
@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>
Gera o seguinte 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>
Nenhuma seleção
Se acabar usando a opção "não especificado" em várias páginas, você poderá criar um modelo para eliminar o HTML de repetição:
@model CountryViewModel
<form asp-controller="Home" asp-action="IndexEmpty" method="post">
@Html.EditorForModel()
<br /><button type="submit">Register</button>
</form>
O modelo Views/Shared/EditorTemplates/CountryViewModel.cshtml:
@model CountryViewModel
<select asp-for="Country" asp-items="Model.Countries">
<option value="">--none--</option>
</select>
O acréscimo de elementos HTML <option> não está limitado ao caso de No selection. Por exemplo, o seguinte método de exibição e ação gerará HTML semelhante ao código anterior:
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>
O elemento correto <option> será selecionado (contém o selected="selected" atributo) dependendo do valor atual 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>