Helper tag nei moduli in ASP.NET Core
Di Rick Anderson, N. Taylor Mullen, Dave Paquette e Jerrie Pelser
Questo documento illustra l'uso di helper tag Form e gli elementi HTML comunemente usati all'interno di questi. L'elemento Form del linguaggio HTML rappresenta il meccanismo principale usato dalle app Web per eseguire il postback di dati nel server. La maggior parte di questo documento descrive gli helper tag e spiega come questi consentono di creare moduli HTML solidi in modo produttivo. Prima di leggere questo documento, è consigliabile leggere Introduzione agli helper tag.
In molti casi, gli helper HTML offrono un approccio alternativo a un helper tag specifico, ma è importante tenere presente che gli helper tag non sostituiscono gli helper HTML e che non esiste un helper tag per ogni helper HTML. Se un'alternativa sotto forma di helper HTML esiste, viene citata.
Helper tag Form
L'helper tag Form:
Genera il valore dell'attributo HTML <FORM>
action
per un'azione del controller MVC o una route denominataGenera un token di verifica della richiesta nascosto per impedire richieste intersito false, in caso di uso con l'attributo
[ValidateAntiForgeryToken]
nel metodo azione HTTP PostFornisce l'attributo
asp-route-<Parameter Name>
, dove<Parameter Name>
viene aggiunto ai valori della route. IrouteValues
parametri perHtml.BeginForm
eHtml.BeginRouteForm
forniscono funzionalità simili.Ha come helper HTML alternativi
Html.BeginForm
eHtml.BeginRouteForm
Esempio:
<form asp-controller="Demo" asp-action="Register" method="post">
<!-- Input and Submit elements -->
</form>
L'helper tag Form precedente genera il codice HTML seguente:
<form method="post" action="/Demo/Register">
<!-- Input and Submit elements -->
<input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>
Il runtime MVC genera il valore dell'attributo action
dagli attributi asp-controller
e asp-action
dell'helper tag Form. L'helper tag Form genera anche un token di verifica della richiesta nascosto per impedire richieste intersito false, in caso di uso con l'attributo [ValidateAntiForgeryToken]
nel metodo azione HTTP Post. La protezione di un Form HTML puro da richieste intersito false è difficile, e l'helper tag Form offre questo servizio.
Uso di una route denominata
L'attributo asp-route
degli helper tag può anche generare un markup per l'attributo action
HTML. Un'app con una route denominata register
può usare il markup seguente per la pagina di registrazione:
<form asp-route="register" method="post">
<!-- Input and Submit elements -->
</form>
Molte delle visualizzazioni nella cartella Views/Account (generata quando si crea una nuova app Web con account utente singoli) contengono l'attributo asp-route-returnurl:
<form asp-controller="Account" asp-action="Login"
asp-route-returnurl="@ViewData["ReturnUrl"]"
method="post" class="form-horizontal" role="form">
Nota
Con i modelli predefiniti, returnUrl
viene popolato automaticamente solo quando si tenta di accedere a una risorsa autorizzata senza aver effettuato l'autenticazione o l'autorizzazione. Se l'utente tenta un accesso non autorizzato, il middleware di sicurezza lo reindirizza alla pagina di accesso con returnUrl
impostato.
Helper tag per l'azione modulo
L'helper tag per l'azione modulo genera l'attributo formaction
per l'elemento <button ...>
o il tag <input type="image" ...>
generato. L'attributo formaction
controlla se un modulo invia i dati. Viene associato agli elementi di input> di tipo image
e< pulsante>.< L'helper tag azione modulo consente l'utilizzo di diversi attributi AnchorTagHelper asp-
per controllare il formaction
collegamento generato per l'elemento corrispondente.
Attributi di AnchorTagHelper supportati per controllare il valore di formaction
:
Attributo | Descrizione |
---|---|
asp-controller | Nome del controller. |
asp-action | Nome del metodo di azione. |
asp-area | Nome dell'area. |
asp-page | Nome della Razor pagina. |
asp-page-handler | Nome del Razor gestore della pagina. |
asp-route | Nome della route. |
asp-route-{value} | Singolo valore di route URL. Ad esempio: asp-route-id="1234" . |
asp-all-route-data | Tutti i valori di route. |
asp-fragment | Frammento di URL. |
Esempio di invio al controller
Il markup seguente invia il modulo all'azione Index
di HomeController
quando viene selezionato l'input o un pulsante:
<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>
Il markup precedente genera il codice HTML seguente:
<form method="post">
<button formaction="/Home">Click Me</button>
<input type="image" src="..." alt="Or Click Me" formaction="/Home">
</form>
Esempio di invio a una pagina
Il markup seguente invia il modulo alla About
Razor pagina:
<form method="post">
<button asp-page="About">Click Me</button>
<input type="image" src="..." alt="Or Click Me" asp-page="About">
</form>
Il markup precedente genera il codice HTML seguente:
<form method="post">
<button formaction="/About">Click Me</button>
<input type="image" src="..." alt="Or Click Me" formaction="/About">
</form>
Esempio di invio a una route
Prendere in considerazione l'endpoint /Home/Test
:
public class HomeController : Controller
{
[Route("/Home/Test", Name = "Custom")]
public string Test()
{
return "This is the test page";
}
}
Il markup seguente invia il modulo all'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>
Il markup precedente genera il codice HTML seguente:
<form method="post">
<button formaction="/Home/Test">Click Me</button>
<input type="image" src="..." alt="Or Click Me" formaction="/Home/Test">
</form>
Helper tag Input
L'helper tag di input associa un elemento di input> HTML <a un'espressione del modello nella razor visualizzazione.
Sintassi:
<input asp-for="<Expression Name>">
L'helper tag Input:
Genera gli attributi HTML
id
ename
per il nome dell'espressione specificata nell'attributoasp-for
.asp-for="Property1.Property2"
è pari am => m.Property1.Property2
. Il nome dell'espressione viene usato come valore dell'attributoasp-for
. Per altre informazioni, vedere la sezione Nomi delle espressioni.Imposta il valore dell'attributo HTML
type
in base agli attributi relativi al tipo di modello e all'annotazione dei dati applicati alla proprietà del modelloNon sovrascrive il valore dell'attributo HTML
type
se è già stato specificatoGenera attributi di convalida HTML5 da attributi di annotazione dei dati applicati alla proprietà del modello
Sovrappone una funzionalità di helper HTML con
Html.TextBoxFor
eHtml.EditorFor
. Per i dettagli, vedere la sezione Alternative helper HTML per l'helper tag Input.Consente una tipizzazione forte. Se il nome di proprietà viene modificato e non si aggiorna l'helper tag, si ottiene un errore simile al seguente:
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?)
L'helper tag Input
imposta l'attributo HTML type
in base al tipo .NET. La tabella seguente elenca alcuni tipi .NET comuni e il tipo HTML generato. Non sono elencati tutti i tipi .NET.
Tipo .NET | Tipo di input |
---|---|
Bool | type="checkbox" |
String | type="text" |
Data/Ora | type="datetime-local" |
Byte | type="number" |
Int | type="number" |
Single, Double | type="number" |
La tabella seguente illustra alcuni attributi di annotazioni dei dati comuni di cui l'helper tag Input esegue il mapping a tipi di input specifici (non tutti gli attributi di convalida sono elencati):
Attributo | Tipo di input |
---|---|
[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="time" |
Esempio:
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>
Il codice precedente genera il codice HTML seguente:
<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>
Le annotazioni dei dati applicate alle proprietà Email
e Password
generano metadati per il modello. L'helper tag di input utilizza i metadati del modello e produce attributi HTML5 data-val-*
(vedere Convalida del modello). Questi attributi descrivono i validator da collegare ai campi di input. Ciò consente una convalida HTML5 e jQuery discreta. Gli attributi non invasivi hanno il formato data-val-rule="Error Message"
, dove regola è il nome della regola di convalida (ad esempio data-val-required
, data-val-email
, data-val-maxlength
e così via) Se viene specificato un messaggio di errore nell'attributo , viene visualizzato come valore per l'attributo data-val-rule
. Esistono anche attributi di data-val-ruleName-argumentName="argumentValue"
di Form che offrono dettagli aggiuntivi sulla regola, ad esempio, data-val-maxlength-max="1024"
.
Quando si associano più input
controlli alla stessa proprietà, i controlli generati condividono lo stesso id
oggetto , che rende il mark-up generato non valido. Per evitare duplicati, specificare l'attributo id
per ogni controllo in modo esplicito.
Rendering dell'input nascosto casella di controllo
Le caselle di controllo in HTML5 non inviano un valore quando sono deselezionate. Per abilitare l'invio di un valore predefinito per una casella di controllo deselezionata, l'helper tag di input genera un input nascosto aggiuntivo per le caselle di controllo.
Si consideri ad esempio il markup seguente Razor che usa l'helper tag di input per una proprietà IsChecked
del modello booleana :
<form method="post">
<input asp-for="@Model.IsChecked" />
<button type="submit">Submit</button>
</form>
Il markup precedente Razor genera markup HTML simile al seguente:
<form method="post">
<input name="IsChecked" type="checkbox" value="true" />
<button type="submit">Submit</button>
<input name="IsChecked" type="hidden" value="false" />
</form>
Il markup HTML precedente mostra un input nascosto aggiuntivo con un nome e IsChecked
un valore di false
. Per impostazione predefinita, il rendering dell'input nascosto viene eseguito alla fine del modulo. Quando viene inviato il modulo:
- Se l'input della
IsChecked
casella di controllo è selezionato, entrambitrue
efalse
vengono inviati come valori. - Se l'input della
IsChecked
casella di controllo è deselezionato, viene inviato solo il valorefalse
di input nascosto.
Il processo di associazione di modelli core ASP.NET legge solo il primo valore quando si esegue l'associazione a un bool
valore, che restituisce true
le caselle false
di controllo e per le caselle di controllo deselezionate.
Per configurare il comportamento del rendering dell'input nascosto, impostare la CheckBoxHiddenInputRenderMode proprietà su MvcViewOptions.HtmlHelperOptions. Ad esempio:
services.Configure<MvcViewOptions>(options =>
options.HtmlHelperOptions.CheckBoxHiddenInputRenderMode =
CheckBoxHiddenInputRenderMode.None);
Il codice precedente disabilita il rendering dell'input nascosto per le caselle di controllo impostando CheckBoxHiddenInputRenderMode
su CheckBoxHiddenInputRenderMode.None. Per tutte le modalità di rendering disponibili, vedere l'enumerazione CheckBoxHiddenInputRenderMode .
Alternative helper HTML per l'helper tag Input
Html.TextBox
, Html.TextBoxFor
, Html.Editor
e Html.EditorFor
hanno funzionalità che si sovrappongono a quelle dell'helper tag Input. L'helper tag Input imposta automaticamente l'attributo type
, mentre Html.TextBox
e Html.TextBoxFor
non lo fanno. Html.Editor
e Html.EditorFor
gestiscono raccolte, oggetti complessi e modelli, mentre l'helper tag Input non lo fa. L'helper Html.EditorFor
tag di input e Html.TextBoxFor
sono fortemente tipizzato (usano espressioni lambda) Html.TextBox
e Html.Editor
non sono (usano nomi di espressione).
HtmlAttributes
Quando eseguono i modelli predefiniti, @Html.Editor()
e @Html.EditorFor()
usano una voce ViewDataDictionary
speciale denominata htmlAttributes
. È possibile aumentare questo comportamento usando i parametri additionalViewData
. La chiave "htmlAttributes" non fa distinzione tra maiuscole e minuscole. La chiave "htmlAttributes" viene gestita in modo analogo all'oggetto htmlAttributes
passato agli helper di input come @Html.TextBox()
.
@Html.EditorFor(model => model.YourProperty,
new { htmlAttributes = new { @class="myCssClass", style="Width:100px" } })
Nomi delle espressioni
Il valore dell'attributo asp-for
è un ModelExpression
e il lato destro di un'espressione lambda. Pertanto, asp-for="Property1"
diventa m => m.Property1
nel codice generato. Per questo motivo il prefisso Model
non è necessario. È possibile usare il carattere "@" per iniziare un'espressione inline, spostandolo prima di m.
:
@{
var joe = "Joe";
}
<input asp-for="@joe">
Genera quanto segue:
<input type="text" id="joe" name="joe" value="Joe">
Con le proprietà delle raccolte, asp-for="CollectionProperty[23].Member"
genera lo stesso nome di asp-for="CollectionProperty[i].Member"
se il valore di i
è 23
.
Quando ASP.NET Core MVC calcola il valore di ModelExpression
, analizza diverse origini, tra cui ModelState
. Considerare <input type="text" asp-for="Name">
. L'attributo value
calcolato è il primo valore non Null da:
- Voce
ModelState
con chiave "Name". - Risultato dell'espressione
Model.Name
.
Esplorazione delle proprietà figlio
È anche possibile passare alle proprietà figlio tramite il percorso delle proprietà del modello di visualizzazione. Si consideri una classe modello più complessa contenente una proprietà Address
figlio.
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; }
}
Nella visualizzazione, viene eseguita l'associazione 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>
Per Address.AddressLine1
viene generato il codice HTML seguente:
<input type="text" id="Address_AddressLine1" name="Address.AddressLine1" value="">
Nomi delle espressioni e raccolte
Esempio di modello contenente una matrice di Colors
:
public class Person
{
public List<string> Colors { get; set; }
public int Age { get; set; }
}
Metodo di azione:
public IActionResult Edit(int id, int colorIndex)
{
ViewData["Index"] = colorIndex;
return View(GetPerson(id));
}
Di seguito Razor viene illustrato come accedere a un elemento specifico 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>
Il Views/Shared/EditorTemplates/String.cshtml
modello:
@model string
<label asp-for="@Model"></label>
<input asp-for="@Model" /> <br />
Esempio di uso di List<T>
:
public class ToDoItem
{
public string Name { get; set; }
public bool IsDone { get; set; }
}
Di seguito Razor viene illustrato come eseguire l'iterazione su una raccolta:
@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>
Il Views/Shared/EditorTemplates/ToDoItem.cshtml
modello:
@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 essere usato se possibile, quando il valore verrà usato in un contesto asp-for
o in un contesto equivalente Html.DisplayFor
. In genere for
è preferibile a foreach
(se lo scenario lo consente) perché non è necessario allocare un enumeratore. Tuttavia, la valutazione di un indicizzatore in un'espressione LINQ può essere dispendiosa e deve essere ridotta al minimo.
Nota
Il codice di esempio commentato precedente illustra come sostituire l'espressione lambda con l'operatore @
per accedere a ogni ToDoItem
nell'elenco.
Helper tag Textarea
Textarea Tag Helper
è simile all'helper Tag Input.
Genera gli attributi e
name
e gli attributi di convalida dei dati dal modello per un <elemento textarea>.id
Consente una tipizzazione forte.
Helper HTML alternativo:
Html.TextAreaFor
Esempio:
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>
Viene generato il codice HTML seguente:
<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>
Helper tag Label
Genera la didascalia e
for
l'attributo dell'etichetta in un <elemento label> per un nome di espressioneHelper HTML alternativo:
Html.LabelFor
.
Offre Label Tag Helper
i vantaggi seguenti rispetto a un elemento etichetta HTML puro:
Si ottiene automaticamente il valore descrittivo dell'etichetta dall'attributo
Display
. Il nome visualizzato desiderato può cambiare nel tempo e la combinazione dell'attributoDisplay
e dell'helper tag Label applica l'attributoDisplay
ovunque venga usato.Meno markup nel codice sorgente
Tipizzazione forte con la proprietà del modello.
Esempio:
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>
Per l'elemento <label>
viene generato il codice HTML seguente:
<label for="Email">Email Address</label>
L'helper tag Label genera il valore dell'attributo for
di "Email", che è l'ID associato all'elemento <input>
. Gli helper tag generano elementi id
e for
coerenti. In questo modo possono essere associati correttamente. La didascalia di questo esempio deriva dall'attributo Display
. Se il modello non contiene un attributo Display
, la didascalia corrisponde al nome della proprietà dell'espressione. Per eseguire l'override della didascalia predefinita, aggiungere una didascalia all'interno del tag di etichetta.
Helper tag di convalida
Ci sono due helper tag di convalida. Validation Message Tag Helper
, che visualizza un messaggio di convalida per una singola proprietà del modello, e Validation Summary Tag Helper
, che visualizza un riepilogo degli errori di convalida. Input Tag Helper
aggiunge attributi di convalida sul lato client HTML5 agli elementi di input in base agli attributi di annotazione dei dati per le classi del modello. La convalida viene eseguita anche per il server. Quando si verifica un errore di convalida, l'helper tag di convalida visualizza questi messaggi di errore.
Helper tag Validation Message
Aggiunge l'attributo HTML5 all'elemento span, che allega i messaggi di errore di convalida nel campo di input della proprietà del modello specificata.
data-valmsg-for="property"
Quando si verifica un errore di convalida sul lato client, jQuery visualizza il messaggio di errore nell'elemento<span>
.La convalida viene eseguita anche nel server. Nei client JavaScript può essere disabilitato e una parte della convalida può essere eseguita solo sul lato server.
Helper HTML alternativo:
Html.ValidationMessageFor
Viene Validation Message Tag Helper
utilizzato con l'attributo asp-validation-for
su un elemento span HTML.
<span asp-validation-for="Email"></span>
L'helper tag Validation Message genera il codice HTML seguente:
<span class="field-validation-valid"
data-valmsg-for="Email"
data-valmsg-replace="true"></span>
In genere si usa dopo Validation Message Tag Helper
un Input
helper tag per la stessa proprietà. In questo modo è possibile visualizzare i messaggi di errore di convalida vicino all'input che ha causato l'errore.
Nota
È necessario avere una visualizzazione con i riferimenti agli script JavaScript e jQuery corretti per la convalida lato client. Per altre informazioni, vedere Convalida del modello.
Se si verifica un errore di convalida sul lato server, ad esempio quando la convalida sul lato server è personalizzata o quando la convalida sul lato client è disabilitata, MVC inserisce il messaggio di errore nel corpo dell'elemento <span>
.
<span class="field-validation-error" data-valmsg-for="Email"
data-valmsg-replace="true">
The Email Address field is required.
</span>
Helper tag Validation Summary
Considera come destinazione gli elementi
<div>
con l'attributoasp-validation-summary
Helper HTML alternativo:
@Html.ValidationSummary
Viene Validation Summary Tag Helper
utilizzato per visualizzare un riepilogo dei messaggi di convalida. Il valore dell'attributo asp-validation-summary
può corrispondere a uno dei valori seguenti:
asp-validation-summary | Messaggi di convalida visualizzati |
---|---|
All |
Livello di modello e proprietà |
ModelOnly |
Modello |
None |
None |
Esempio
Nell'esempio seguente il modello di dati ha DataAnnotation
attributi, che genera messaggi di errore di convalida sull'elemento <input>
. Quando si verifica un errore di convalida, l'helper tag di convalida visualizza il messaggio di errore:
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>
Codice HTML generato (se il modello è valido):
<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>
Helper tag Select
Genera l'elemento select e gli elementi option associati per le proprietà del modello.
Ha come helper HTML alternativi
Html.DropDownListFor
eHtml.ListBoxFor
Specifica il nome della proprietà del modello per l'elemento select e asp-items
specifica gli elementi dell'opzione.Select Tag Helper
asp-for
Ad esempio:
<select asp-for="Country" asp-items="Model.Countries"></select>
Esempio:
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" },
};
}
}
Il metodo Index
inizializza CountryViewModel
, imposta il paese selezionato e lo passa alla visualizzazione Index
.
public IActionResult Index()
{
var model = new CountryViewModel();
model.Country = "CA";
return View(model);
}
Il metodo Index
di HTTP POST visualizza la selezione:
[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);
}
Visualizzazione 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>
Che genera il codice HTML seguente (con "CA" selezionato):
<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>
Nota
Non è consigliabile usare ViewBag
o ViewData
con l'helper tag Select. Un modello di visualizzazione è più solido e in genere presenta meno problemi quando si tratta di fornire metadati MVC.
Il valore dell'attributo asp-for
rappresenta un caso speciale e non richiede un prefisso Model
, che invece è richiesto dagli altri attributi di helper tag, ad esempio asp-items
<select asp-for="Country" asp-items="Model.Countries"></select>
Associazione di enum
Spesso è comodo usare <select>
con una proprietà enum
e generare gli elementi SelectListItem
dai valori enum
.
Esempio:
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
}
}
Il metodo GetEnumSelectList
genera un oggetto SelectList
per un enum.
@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>
È possibile contrassegnare l'elenco di enumeratori con l'attributo per ottenere un'interfaccia Display
utente più completa:
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
}
}
Viene generato il codice HTML seguente:
<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>
Gruppo di opzioni
L'elemento optgroup> HTML <viene generato quando il modello di visualizzazione contiene uno o più SelectListGroup
oggetti.
CountryViewModelGroup
suddivide gli elementi SelectListItem
nei gruppi "North America" ed "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; }
I due gruppi sono illustrati di seguito:
Codice HTML generato:
<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>
Selezione multipla
L'helper tag Select genera automaticamente l'attributo multiple = "multiple" se la proprietà specificata nell'attributo asp-for
è IEnumerable
. Dato, ad esempio, il modello seguente:
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"}
};
}
}
Con la visualizzazione seguente:
@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>
Viene generato il codice HTML seguente:
<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>
Nessuna selezione
Se si usa l'opzione "not specified" in più pagine, è possibile creare un modello per evitare di ripetere lo stesso codice HTML:
@model CountryViewModel
<form asp-controller="Home" asp-action="IndexEmpty" method="post">
@Html.EditorForModel()
<br /><button type="submit">Register</button>
</form>
Il Views/Shared/EditorTemplates/CountryViewModel.cshtml
modello:
@model CountryViewModel
<select asp-for="Country" asp-items="Model.Countries">
<option value="">--none--</option>
</select>
L'aggiunta di elementi di opzione> HTML <non è limitata al caso Nessuna selezione. La visualizzazione e il metodo di azione seguenti, ad esempio, generano codice HTML simile al codice precedente:
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>
L'elemento <option>
corretto viene selezionato (con l'attributo selected="selected"
) a seconda del valore Country
corrente.
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>