Parte 9, aggiungere la convalida a un'app MVC core ASP.NET
Nota
Questa non è la versione più recente di questo articolo. Per la versione corrente, vedere la versione .NET 8 di questo articolo.
Avviso
Questa versione di ASP.NET Core non è più supportata. Per altre informazioni, vedere Criteri di supporto di .NET e .NET Core. Per la versione corrente, vedere la versione .NET 8 di questo articolo.
Importante
Queste informazioni si riferiscono a un prodotto non definitive che può essere modificato in modo sostanziale prima che venga rilasciato commercialmente. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.
Per la versione corrente, vedere la versione .NET 8 di questo articolo.
Contenuto della sezione:
- La logica di convalida viene aggiunta al modello
Movie
. - Si verifica che le regole di convalida vengano applicate ogni volta che un utente crea o modifica un film.
Rispetto del principio DRY
Uno dei principi di progettazione MVC è DRY ("Don't Repeat Yourself"). ASP.NET Core MVC promuove la specifica delle funzionalità o del comportamento una sola volta, con successiva applicazione ovunque in un'app. In questo modo si riduce la quantità di codice che è necessario scrivere e si rende il codice meno soggetto a errori, più semplice da testare e gestire.
Il supporto di convalida fornito da MVC ed Entity Framework Core è un buon esempio del principio DRY in azione. È possibile specificare in modo dichiarativo le regole di convalida in un'unica posizione (nella classe del modello) e le regole vengono applicate ovunque nell'app.
Eliminare i dati modificati in precedenza
Nel passaggio successivo vengono aggiunte regole di convalida che non consentono valori Null.
Eseguire l'app, passare a /Movies/Index
, eliminare tutti i film elencati e arrestare l'app. L'app userà i dati di inizializzazione alla successiva esecuzione.
Aggiungere regole di convalida al modello movie
Lo spazio dei nomi DataAnnotations offre un set di attributi di convalida predefiniti che vengono applicati in modo dichiarativo a una classe o una proprietà. DataAnnotations contiene anche gli attributi di formattazione come DataType
che guidano nella formattazione e non offrono alcuna convalida.
Aggiornare la Movie
classe per sfruttare i vantaggi degli attributi Required
di convalida predefiniti , , RegularExpression
StringLength
Range
e dell'attributo DataType
di formattazione.
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace MvcMovie.Models;
public class Movie
{
public int Id { get; set; }
[StringLength(60, MinimumLength = 3)]
[Required]
public string? Title { get; set; }
[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
[Range(1, 100)]
[DataType(DataType.Currency)]
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$")]
[Required]
[StringLength(30)]
public string? Genre { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$")]
[StringLength(5)]
[Required]
public string? Rating { get; set; }
}
Gli attributi di convalida specificano il comportamento da implementare nelle proprietà del modello a cui vengono applicati:
Gli attributi
Required
eMinimumLength
indicano che una proprietà deve avere un valore, ma nulla impedisce all'utente di inserire spazi vuoti per soddisfare questa convalida.L'attributo
RegularExpression
viene usato per limitare i caratteri che possono essere inseriti. Nel codice precedente "Genre":- Deve includere solo lettere.
- La prima lettera deve essere maiuscola. Gli spazi vuoti sono consentiti mentre i numeri e i caratteri speciali non sono consentiti.
RegularExpression
"Rating":- Richiede che il primo carattere sia una lettera maiuscola.
- Consente i caratteri speciali e i numeri negli spazi successivi. "PG-13" è valido per una classificazione, ma non per "Genre".
L'attributo
Range
vincola un valore all'interno di un intervallo specificato.L'attributo
StringLength
consente di impostare la lunghezza massima di una proprietà stringa e, facoltativamente, la lunghezza minima.I tipi di valore, ad esempio
decimal
,int
,float
eDateTime
, sono intrinsecamente necessari e non richiedono l'attributo[Required]
.
L'applicazione automatica di regole di convalida da ASP.NET Core è utile per rendere un'app più solida. In questo modo inoltre non è possibile omettere la convalida di un elemento e quindi inserire involontariamente dati errati nel database.
Interfaccia utente dell'errore di convalida
Eseguire l'app e passare al controller di film.
Selezionare il collegamento Crea nuovo per aggiungere un nuovo film. Completare il modulo con alcuni valori non validi. Non appena la convalida del lato client jQuery rileva l'errore, viene visualizzato un messaggio di errore.
Nota
È possibile che non si riesca a immettere virgole decimali nel campo. Per supportare la convalida jQuery per impostazioni locali diverse dall'inglese che usano la virgola (",") come separatore decimale e per formati di data diversi da quello dell'inglese degli Stati Uniti, è necessario eseguire alcuni passaggi per globalizzare l'app. Per istruzioni sull'aggiunta di una virgola decimale, vedere questo commento di GitHub 4076 .
Si noti come il modulo ha eseguito automaticamente il rendering di un messaggio di errore di convalida appropriato in ogni campo contenente un valore non valido. Gli errori vengono applicati sia sul lato client (utilizzo di JavaScript e jQuery) sia sul lato server (nel caso di un utente con JavaScript disabilitato).
Un vantaggio significativo è che non è necessario modificare una singola riga di codice nella MoviesController
classe o nella Create.cshtml
visualizzazione per abilitare questa interfaccia utente di convalida. Il controller e le viste creati in una fase precedente di questa esercitazione hanno selezionato automaticamente le regole di convalida specificate usando gli attributi di convalida delle proprietà della classe Movie
del modello. Eseguire il test della convalida usando il metodo di azione Edit
e viene applicata la stessa convalida.
I dati del modulo non vengono inviati al server fino a quando non sono più presenti errori di convalida sul lato client. È possibile verificare questa condizione inserendo un punto di interruzione nel metodo HTTP Post
usando lo strumento Fiddler o gli strumenti di sviluppo F12.
Funzionamento della convalida
Ci si potrebbe chiedere come la convalida dell'interfaccia utente sia stata generata senza aggiornamenti al codice nel controller o nelle viste. Il codice seguente mostra i due metodi Create
.
// GET: Movies/Create
public IActionResult Create()
{
return View();
}
// POST: Movies/Create
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
if (ModelState.IsValid)
{
_context.Add(movie);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(movie);
}
Il primo metodo di azione (HTTP GET) Create
visualizza il modulo di creazione iniziale. La seconda versione ([HttpPost]
) gestisce l'invio del modulo. Il secondo metodo Create
(la versione [HttpPost]
) chiama ModelState.IsValid
per verificare se esistono errori di convalida per il film. La chiamata a questo metodo valuta tutti gli attributi di convalida applicati all'oggetto. Se l'oggetto presenta errori di convalida, il metodo Create
visualizza di nuovo il modulo. Se non sono presenti errori, il metodo salva il nuovo film nel database. Nell'esempio del film, il modulo non viene inviato al server quando vengono rilevati errori di convalida sul lato client; il secondo metodo Create
non viene mai chiamato quando sono presenti errori di convalida sul lato client. Se si disabilita JavaScript nel browser, la convalida sul lato client viene disabilitata ed è possibile testare ModelState.IsValid
del metodo Create
HTTP POST rilevando eventuali errori di convalida.
È possibile impostare un punto di interruzione nel metodo [HttpPost] Create
e verificare che il metodo non venga mai chiamato, la convalida sul lato client non invierà i dati del modulo in caso di rilevamento di errori di convalida. Se si disabilita JavaScript nel browser, quindi si invia il modulo con errori, verrà raggiunto il punto di interruzione. Si ottiene comunque la convalida completa senza JavaScript.
L'immagine seguente mostra come disabilitare JavaScript nel browser Firefox.
La figura seguente illustra come disabilitare JavaScript nel browser Chrome.
Dopo avere disabilitato JavaScript, inviare i dati non validi e procedere con il debugger.
Una parte del Create.cshtml
modello di visualizzazione è illustrata nel markup seguente:
<h4>Movie</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Title" class="control-label"></label>
<input asp-for="Title" class="form-control" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
@*Markup removed for brevity.*@
Il markup precedente viene usato dai metodi di azione per visualizzare il modulo iniziale e per visualizzarlo nuovamente in caso di errore.
L'helper tag di input usa gli attributi DataAnnotations e produce gli attributi HTML necessari per la convalida jQuery sul lato client. L'helper tag di convalida visualizza gli errori di convalida. Per altre informazioni, vedere Convalida.
L'aspetto molto interessante di questo approccio è che né il controller né il modello di vista Create
sono consapevoli delle regole di convalida effettive applicate o dei messaggi di errore specifici visualizzati. Le regole di convalida e le stringhe di errore vengono specificate solo nella classe Movie
. Le stesse regole di convalida vengono applicate automaticamente alla vista Edit
e ad altri modelli di vista eventualmente creati che modificano il modello.
Se necessario, è possibile modificare la logica di convalida in una posizione tramite l'aggiunta di attributi di convalida al modello, in questo esempio la classe Movie
. Non è necessario preoccuparsi dell'incoerenza delle diverse parti dell'applicazione con la modalità di applicazione delle regole perché tutta la logica di convalida verrà definita in un'unica posizione e usata ovunque. In questo modo il codice rimane molto pulito e facile da gestire e sviluppare. Il principio DRY sarà ampiamente rispettato.
Utilizzo degli attributi DataType
Aprire il Movie.cs
file ed esaminare la Movie
classe . Lo spazio dei nomi System.ComponentModel.DataAnnotations
fornisce gli attributi di formattazione oltre al set predefinito di attributi di convalida. È già stato applicato un valore di enumerazione DataType
ai campi della data di rilascio e del prezzo. Il codice seguente illustra le proprietà ReleaseDate
e Price
con l'attributo appropriato DataType
.
[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
[Range(1, 100)]
[DataType(DataType.Currency)]
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }
Gli DataType
attributi forniscono solo suggerimenti per il motore di visualizzazione per formattare i dati e fornire elementi/attributi, ad <a>
esempio per l'URL e <a href="mailto:EmailAddress.com">
per il messaggio di posta elettronica. È possibile usare l'attributo RegularExpression
per convalidare il formato dei dati. L'attributo DataType
viene usato per specificare un tipo di dati più specifico del tipo intrinseco del database; non si tratta di attributi di convalida. In questo caso si vuole solo tenere traccia della data, non dell'ora. L'enumerazione DataType
fornisce molti tipi di dati, ad esempio Data, Ora, Numero di telefono, Valuta, Indirizzo di posta elettronica e altro ancora. L'attributo DataType
può anche consentire all'applicazione di fornire automaticamente le funzionalità specifiche del tipo. Ad esempio, è possibile creare un collegamento mailto:
per DataType.EmailAddress
e fornire un selettore data per DataType.Date
nei browser che supportano HTML5. Gli attributi DataType
generano attributi data-
HTML5 (pronunciato data dash) supportati dai browser HTML5. Gli attributi DataType
non forniscono alcuna convalida.
DataType.Date
non specifica il formato della data visualizzata. Per impostazione predefinita, il campo dei dati viene visualizzato in base ai formati predefiniti per il valore CultureInfo
del server.
L'attributo DisplayFormat
viene usato per specificare in modo esplicito il formato della data:
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }
L'impostazione ApplyFormatInEditMode
specifica che la formattazione deve essere applicata anche quando il valore viene visualizzato in una casella di testo per la modifica. Questa scelta non è consigliabile per alcuni campi, ad esempio per i valori della valuta poiché non è opportuno che il simbolo di valuta sia inserito nella casella di testo per la modifica.
È possibile usare l'attributo DisplayFormat
da solo, ma in genere è consigliabile usare l'attributo DataType
. L'attributo DataType
fornisce la semantica dei dati anziché la modalità di esecuzione del rendering in una schermata e fornisce i seguenti vantaggi che non si ottengono con DisplayFormat:
Il browser può abilitare le funzionalità HTML5, ad esempio visualizzare un controllo di calendario, il simbolo della valuta appropriato per le impostazioni locali, i collegamenti alla posta elettronica e così via.
Per impostazione predefinita, il browser eseguirà il rendering dei dati usando il formato corretto in base alle impostazioni locali del sistema.
L'attributo
DataType
consente di abilitare MVC in modo da scegliere il modello di campo corretto per il rendering dei dati (DisplayFormat
, se usato da solo, usa il modello di stringa).
Nota
La convalida jQuery non funziona con l'attributo Range
e con DateTime
. Ad esempio, il codice seguente visualizzerà sempre un errore di convalida sul lato client, anche quando la data è compreso nell'intervallo specificato:
[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]
È necessario disabilitare la convalida della data jQuery per usare l'attributo Range
con DateTime
. In genere non è consigliabile compilare date reali nei modelli, quindi l'uso dell'attributo Range
e di DateTime
è sconsigliato.
Il codice seguente illustra la combinazione di attributi in una sola riga:
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace MvcMovie.Models;
public class Movie
{
public int Id { get; set; }
[StringLength(60, MinimumLength = 3)]
public string Title { get; set; }
[Display(Name = "Release Date"), DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$"), Required, StringLength(30)]
public string Genre { get; set; }
[Range(1, 100), DataType(DataType.Currency)]
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$"), StringLength(5)]
public string Rating { get; set; }
}
Nella parte successiva della serie viene esaminata l'app e vengono apportati alcuni miglioramenti ai metodi Details
e Delete
generati automaticamente.
Risorse aggiuntive
Contenuto della sezione:
- La logica di convalida viene aggiunta al modello
Movie
. - Si verifica che le regole di convalida vengano applicate ogni volta che un utente crea o modifica un film.
Rispetto del principio DRY
Uno dei principi di progettazione MVC è DRY ("Don't Repeat Yourself"). ASP.NET Core MVC promuove la specifica delle funzionalità o del comportamento una sola volta, con successiva applicazione ovunque in un'app. In questo modo si riduce la quantità di codice che è necessario scrivere e si rende il codice meno soggetto a errori, più semplice da testare e gestire.
Il supporto della convalida fornito da MVC ed Entity Framework Core Code First è un valido esempio pratico del principio DRY. È possibile specificare in modo dichiarativo le regole di convalida in un'unica posizione (nella classe del modello) e le regole vengono applicate ovunque nell'app.
Eliminare i dati modificati in precedenza
Nel passaggio successivo vengono aggiunte regole di convalida che non consentono valori Null.
Eseguire l'app, passare a /Movies/Index
, eliminare tutti i film elencati e arrestare l'app. L'app userà i dati di inizializzazione alla successiva esecuzione.
Aggiungere regole di convalida al modello movie
Lo spazio dei nomi DataAnnotations offre un set di attributi di convalida predefiniti che vengono applicati in modo dichiarativo a una classe o una proprietà. DataAnnotations contiene anche gli attributi di formattazione come DataType
che guidano nella formattazione e non offrono alcuna convalida.
Aggiornare la Movie
classe per sfruttare i vantaggi degli attributi Required
di convalida predefiniti , , RegularExpression
StringLength
Range
e dell'attributo DataType
di formattazione.
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace MvcMovie.Models;
public class Movie
{
public int Id { get; set; }
[StringLength(60, MinimumLength = 3)]
[Required]
public string? Title { get; set; }
[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
[Range(1, 100)]
[DataType(DataType.Currency)]
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$")]
[Required]
[StringLength(30)]
public string? Genre { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$")]
[StringLength(5)]
[Required]
public string? Rating { get; set; }
}
Gli attributi di convalida specificano il comportamento da implementare nelle proprietà del modello a cui vengono applicati:
Gli attributi
Required
eMinimumLength
indicano che una proprietà deve avere un valore, ma nulla impedisce all'utente di inserire spazi vuoti per soddisfare questa convalida.L'attributo
RegularExpression
viene usato per limitare i caratteri che possono essere inseriti. Nel codice precedente "Genre":- Deve includere solo lettere.
- La prima lettera deve essere maiuscola. Gli spazi vuoti sono consentiti mentre i numeri e i caratteri speciali non sono consentiti.
RegularExpression
"Rating":- Richiede che il primo carattere sia una lettera maiuscola.
- Consente i caratteri speciali e i numeri negli spazi successivi. "PG-13" è valido per una classificazione, ma non per "Genre".
L'attributo
Range
vincola un valore all'interno di un intervallo specificato.L'attributo
StringLength
consente di impostare la lunghezza massima di una proprietà stringa e, facoltativamente, la lunghezza minima.I tipi di valore, ad esempio
decimal
,int
,float
eDateTime
, sono intrinsecamente necessari e non richiedono l'attributo[Required]
.
L'applicazione automatica di regole di convalida da ASP.NET Core è utile per rendere un'app più solida. In questo modo inoltre non è possibile omettere la convalida di un elemento e quindi inserire involontariamente dati errati nel database.
Interfaccia utente dell'errore di convalida
Eseguire l'app e passare al controller di film.
Selezionare il collegamento Crea nuovo per aggiungere un nuovo film. Completare il modulo con alcuni valori non validi. Non appena la convalida del lato client jQuery rileva l'errore, viene visualizzato un messaggio di errore.
Nota
È possibile che non si riesca a immettere virgole decimali nel campo. Per supportare la convalida jQuery per impostazioni locali diverse dall'inglese che usano la virgola (",") come separatore decimale e per formati di data diversi da quello dell'inglese degli Stati Uniti, è necessario eseguire alcuni passaggi per globalizzare l'app. Per istruzioni sull'aggiunta di una virgola decimale, vedere questo commento di GitHub 4076 .
Si noti come il modulo ha eseguito automaticamente il rendering di un messaggio di errore di convalida appropriato in ogni campo contenente un valore non valido. Gli errori vengono applicati sia sul lato client (utilizzo di JavaScript e jQuery) sia sul lato server (nel caso di un utente con JavaScript disabilitato).
Un vantaggio significativo è che non è necessario modificare una singola riga di codice nella MoviesController
classe o nella Create.cshtml
visualizzazione per abilitare questa interfaccia utente di convalida. Il controller e le viste creati in una fase precedente di questa esercitazione hanno selezionato automaticamente le regole di convalida specificate usando gli attributi di convalida delle proprietà della classe Movie
del modello. Eseguire il test della convalida usando il metodo di azione Edit
e viene applicata la stessa convalida.
I dati del modulo non vengono inviati al server fino a quando non sono più presenti errori di convalida sul lato client. È possibile verificare questa condizione inserendo un punto di interruzione nel metodo HTTP Post
usando lo strumento Fiddler o gli strumenti di sviluppo F12.
Funzionamento della convalida
Ci si potrebbe chiedere come la convalida dell'interfaccia utente sia stata generata senza aggiornamenti al codice nel controller o nelle viste. Il codice seguente mostra i due metodi Create
.
// GET: Movies/Create
public IActionResult Create()
{
return View();
}
// POST: Movies/Create
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
if (ModelState.IsValid)
{
_context.Add(movie);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(movie);
}
Il primo metodo di azione (HTTP GET) Create
visualizza il modulo di creazione iniziale. La seconda versione ([HttpPost]
) gestisce l'invio del modulo. Il secondo metodo Create
(la versione [HttpPost]
) chiama ModelState.IsValid
per verificare se esistono errori di convalida per il film. La chiamata a questo metodo valuta tutti gli attributi di convalida applicati all'oggetto. Se l'oggetto presenta errori di convalida, il metodo Create
visualizza di nuovo il modulo. Se non sono presenti errori, il metodo salva il nuovo film nel database. Nell'esempio del film, il modulo non viene inviato al server quando vengono rilevati errori di convalida sul lato client; il secondo metodo Create
non viene mai chiamato quando sono presenti errori di convalida sul lato client. Se si disabilita JavaScript nel browser, la convalida sul lato client viene disabilitata ed è possibile testare ModelState.IsValid
del metodo Create
HTTP POST rilevando eventuali errori di convalida.
È possibile impostare un punto di interruzione nel metodo [HttpPost] Create
e verificare che il metodo non venga mai chiamato, la convalida sul lato client non invierà i dati del modulo in caso di rilevamento di errori di convalida. Se si disabilita JavaScript nel browser, quindi si invia il modulo con errori, verrà raggiunto il punto di interruzione. Si ottiene comunque la convalida completa senza JavaScript.
L'immagine seguente mostra come disabilitare JavaScript nel browser Firefox.
La figura seguente illustra come disabilitare JavaScript nel browser Chrome.
Dopo avere disabilitato JavaScript, inviare i dati non validi e procedere con il debugger.
Una parte del Create.cshtml
modello di visualizzazione è illustrata nel markup seguente:
<h4>Movie</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Title" class="control-label"></label>
<input asp-for="Title" class="form-control" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
@*Markup removed for brevity.*@
Il markup precedente viene usato dai metodi di azione per visualizzare il modulo iniziale e per visualizzarlo nuovamente in caso di errore.
L'helper tag di input usa gli attributi DataAnnotations e produce gli attributi HTML necessari per la convalida jQuery sul lato client. L'helper tag di convalida visualizza gli errori di convalida. Per altre informazioni, vedere Convalida.
L'aspetto molto interessante di questo approccio è che né il controller né il modello di vista Create
sono consapevoli delle regole di convalida effettive applicate o dei messaggi di errore specifici visualizzati. Le regole di convalida e le stringhe di errore vengono specificate solo nella classe Movie
. Le stesse regole di convalida vengono applicate automaticamente alla vista Edit
e ad altri modelli di vista eventualmente creati che modificano il modello.
Se necessario, è possibile modificare la logica di convalida in una posizione tramite l'aggiunta di attributi di convalida al modello, in questo esempio la classe Movie
. Non è necessario preoccuparsi dell'incoerenza delle diverse parti dell'applicazione con la modalità di applicazione delle regole perché tutta la logica di convalida verrà definita in un'unica posizione e usata ovunque. In questo modo il codice rimane molto pulito e facile da gestire e sviluppare. Il principio DRY sarà ampiamente rispettato.
Utilizzo degli attributi DataType
Aprire il Movie.cs
file ed esaminare la Movie
classe . Lo spazio dei nomi System.ComponentModel.DataAnnotations
fornisce gli attributi di formattazione oltre al set predefinito di attributi di convalida. È già stato applicato un valore di enumerazione DataType
ai campi della data di rilascio e del prezzo. Il codice seguente illustra le proprietà ReleaseDate
e Price
con l'attributo appropriato DataType
.
[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
[Range(1, 100)]
[DataType(DataType.Currency)]
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }
Gli DataType
attributi forniscono solo suggerimenti per il motore di visualizzazione per formattare i dati e fornire elementi/attributi, ad <a>
esempio per l'URL e <a href="mailto:EmailAddress.com">
per il messaggio di posta elettronica. È possibile usare l'attributo RegularExpression
per convalidare il formato dei dati. L'attributo DataType
viene usato per specificare un tipo di dati più specifico del tipo intrinseco del database; non si tratta di attributi di convalida. In questo caso si vuole solo tenere traccia della data, non dell'ora. L'enumerazione DataType
fornisce molti tipi di dati, ad esempio Data, Ora, Numero di telefono, Valuta, Indirizzo di posta elettronica e altro ancora. L'attributo DataType
può anche consentire all'applicazione di fornire automaticamente le funzionalità specifiche del tipo. Ad esempio, è possibile creare un collegamento mailto:
per DataType.EmailAddress
e fornire un selettore data per DataType.Date
nei browser che supportano HTML5. Gli attributi DataType
generano attributi data-
HTML5 (pronunciato data dash) supportati dai browser HTML5. Gli attributi DataType
non forniscono alcuna convalida.
DataType.Date
non specifica il formato della data visualizzata. Per impostazione predefinita, il campo dei dati viene visualizzato in base ai formati predefiniti per il valore CultureInfo
del server.
L'attributo DisplayFormat
viene usato per specificare in modo esplicito il formato della data:
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }
L'impostazione ApplyFormatInEditMode
specifica che la formattazione deve essere applicata anche quando il valore viene visualizzato in una casella di testo per la modifica. Questa scelta non è consigliabile per alcuni campi, ad esempio per i valori della valuta poiché non è opportuno che il simbolo di valuta sia inserito nella casella di testo per la modifica.
È possibile usare l'attributo DisplayFormat
da solo, ma in genere è consigliabile usare l'attributo DataType
. L'attributo DataType
fornisce la semantica dei dati anziché la modalità di esecuzione del rendering in una schermata e fornisce i seguenti vantaggi che non si ottengono con DisplayFormat:
Il browser può abilitare le funzionalità HTML5, ad esempio visualizzare un controllo di calendario, il simbolo della valuta appropriato per le impostazioni locali, i collegamenti alla posta elettronica e così via.
Per impostazione predefinita, il browser eseguirà il rendering dei dati usando il formato corretto in base alle impostazioni locali del sistema.
L'attributo
DataType
consente di abilitare MVC in modo da scegliere il modello di campo corretto per il rendering dei dati (DisplayFormat
, se usato da solo, usa il modello di stringa).
Nota
La convalida jQuery non funziona con l'attributo Range
e con DateTime
. Ad esempio, il codice seguente visualizzerà sempre un errore di convalida sul lato client, anche quando la data è compreso nell'intervallo specificato:
[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]
È necessario disabilitare la convalida della data jQuery per usare l'attributo Range
con DateTime
. In genere non è consigliabile compilare date reali nei modelli, quindi l'uso dell'attributo Range
e di DateTime
è sconsigliato.
Il codice seguente illustra la combinazione di attributi in una sola riga:
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace MvcMovie.Models;
public class Movie
{
public int Id { get; set; }
[StringLength(60, MinimumLength = 3)]
public string Title { get; set; }
[Display(Name = "Release Date"), DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$"), Required, StringLength(30)]
public string Genre { get; set; }
[Range(1, 100), DataType(DataType.Currency)]
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$"), StringLength(5)]
public string Rating { get; set; }
}
Nella parte successiva della serie viene esaminata l'app e vengono apportati alcuni miglioramenti ai metodi Details
e Delete
generati automaticamente.
Risorse aggiuntive
Contenuto della sezione:
- La logica di convalida viene aggiunta al modello
Movie
. - Si verifica che le regole di convalida vengano applicate ogni volta che un utente crea o modifica un film.
Rispetto del principio DRY
Uno dei principi di progettazione MVC è DRY ("Don't Repeat Yourself"). ASP.NET Core MVC promuove la specifica delle funzionalità o del comportamento una sola volta, con successiva applicazione ovunque in un'app. In questo modo si riduce la quantità di codice che è necessario scrivere e si rende il codice meno soggetto a errori, più semplice da testare e gestire.
Il supporto della convalida fornito da MVC ed Entity Framework Core Code First è un valido esempio pratico del principio DRY. È possibile specificare in modo dichiarativo le regole di convalida in un'unica posizione (nella classe del modello) e le regole vengono applicate ovunque nell'app.
Aggiungere regole di convalida al modello movie
Lo spazio dei nomi DataAnnotations offre un set di attributi di convalida predefiniti che vengono applicati in modo dichiarativo a una classe o una proprietà. DataAnnotations contiene anche gli attributi di formattazione come DataType
che guidano nella formattazione e non offrono alcuna convalida.
Aggiornare la Movie
classe per sfruttare i vantaggi degli attributi Required
di convalida predefiniti , , RegularExpression
StringLength
Range
e dell'attributo DataType
di formattazione.
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace MvcMovie.Models;
public class Movie
{
public int Id { get; set; }
[StringLength(60, MinimumLength = 3)]
[Required]
public string? Title { get; set; }
[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
[Range(1, 100)]
[DataType(DataType.Currency)]
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$")]
[Required]
[StringLength(30)]
public string? Genre { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$")]
[StringLength(5)]
[Required]
public string? Rating { get; set; }
}
Gli attributi di convalida specificano il comportamento da implementare nelle proprietà del modello a cui vengono applicati:
Gli attributi
Required
eMinimumLength
indicano che una proprietà deve avere un valore, ma nulla impedisce all'utente di inserire spazi vuoti per soddisfare questa convalida.L'attributo
RegularExpression
viene usato per limitare i caratteri che possono essere inseriti. Nel codice precedente "Genre":- Deve includere solo lettere.
- La prima lettera deve essere maiuscola. Gli spazi vuoti sono consentiti mentre i numeri e i caratteri speciali non sono consentiti.
RegularExpression
"Rating":- Richiede che il primo carattere sia una lettera maiuscola.
- Consente i caratteri speciali e i numeri negli spazi successivi. "PG-13" è valido per una classificazione, ma non per "Genre".
L'attributo
Range
vincola un valore all'interno di un intervallo specificato.L'attributo
StringLength
consente di impostare la lunghezza massima di una proprietà stringa e, facoltativamente, la lunghezza minima.I tipi di valore, ad esempio
decimal
,int
,float
eDateTime
, sono intrinsecamente necessari e non richiedono l'attributo[Required]
.
L'applicazione automatica di regole di convalida da ASP.NET Core è utile per rendere un'app più solida. In questo modo inoltre non è possibile omettere la convalida di un elemento e quindi inserire involontariamente dati errati nel database.
Interfaccia utente dell'errore di convalida
Eseguire l'app e passare al controller di film.
Selezionare il collegamento Crea nuovo per aggiungere un nuovo film. Completare il modulo con alcuni valori non validi. Non appena la convalida del lato client jQuery rileva l'errore, viene visualizzato un messaggio di errore.
Nota
È possibile che non si riesca a immettere virgole decimali nel campo. Per supportare la convalida jQuery per impostazioni locali diverse dall'inglese che usano la virgola (",") come separatore decimale e per formati di data diversi da quello dell'inglese degli Stati Uniti, è necessario eseguire alcuni passaggi per globalizzare l'app. Per istruzioni sull'aggiunta di una virgola decimale, vedere questo commento di GitHub 4076 .
Si noti come il modulo ha eseguito automaticamente il rendering di un messaggio di errore di convalida appropriato in ogni campo contenente un valore non valido. Gli errori vengono applicati sia sul lato client (utilizzo di JavaScript e jQuery) sia sul lato server (nel caso di un utente con JavaScript disabilitato).
Un vantaggio significativo è che non è necessario modificare una singola riga di codice nella MoviesController
classe o nella Create.cshtml
visualizzazione per abilitare questa interfaccia utente di convalida. Il controller e le viste creati in una fase precedente di questa esercitazione hanno selezionato automaticamente le regole di convalida specificate usando gli attributi di convalida delle proprietà della classe Movie
del modello. Eseguire il test della convalida usando il metodo di azione Edit
e viene applicata la stessa convalida.
I dati del modulo non vengono inviati al server fino a quando non sono più presenti errori di convalida sul lato client. È possibile verificare questa condizione inserendo un punto di interruzione nel metodo HTTP Post
usando lo strumento Fiddler o gli strumenti di sviluppo F12.
Funzionamento della convalida
Ci si potrebbe chiedere come la convalida dell'interfaccia utente sia stata generata senza aggiornamenti al codice nel controller o nelle viste. Il codice seguente mostra i due metodi Create
.
// GET: Movies/Create
public IActionResult Create()
{
return View();
}
// POST: Movies/Create
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
if (ModelState.IsValid)
{
_context.Add(movie);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(movie);
}
Il primo metodo di azione (HTTP GET) Create
visualizza il modulo di creazione iniziale. La seconda versione ([HttpPost]
) gestisce l'invio del modulo. Il secondo metodo Create
(la versione [HttpPost]
) chiama ModelState.IsValid
per verificare se esistono errori di convalida per il film. La chiamata a questo metodo valuta tutti gli attributi di convalida applicati all'oggetto. Se l'oggetto presenta errori di convalida, il metodo Create
visualizza di nuovo il modulo. Se non sono presenti errori, il metodo salva il nuovo film nel database. Nell'esempio del film, il modulo non viene inviato al server quando vengono rilevati errori di convalida sul lato client; il secondo metodo Create
non viene mai chiamato quando sono presenti errori di convalida sul lato client. Se si disabilita JavaScript nel browser, la convalida sul lato client viene disabilitata ed è possibile testare ModelState.IsValid
del metodo Create
HTTP POST rilevando eventuali errori di convalida.
È possibile impostare un punto di interruzione nel metodo [HttpPost] Create
e verificare che il metodo non venga mai chiamato, la convalida sul lato client non invierà i dati del modulo in caso di rilevamento di errori di convalida. Se si disabilita JavaScript nel browser, quindi si invia il modulo con errori, verrà raggiunto il punto di interruzione. Si ottiene comunque la convalida completa senza JavaScript.
L'immagine seguente mostra come disabilitare JavaScript nel browser Firefox.
La figura seguente illustra come disabilitare JavaScript nel browser Chrome.
Dopo avere disabilitato JavaScript, inviare i dati non validi e procedere con il debugger.
Una parte del Create.cshtml
modello di visualizzazione è illustrata nel markup seguente:
<h4>Movie</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Title" class="control-label"></label>
<input asp-for="Title" class="form-control" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
@*Markup removed for brevity.*@
Il markup precedente viene usato dai metodi di azione per visualizzare il modulo iniziale e per visualizzarlo nuovamente in caso di errore.
L'helper tag di input usa gli attributi DataAnnotations e produce gli attributi HTML necessari per la convalida jQuery sul lato client. L'helper tag di convalida visualizza gli errori di convalida. Per altre informazioni, vedere Convalida.
L'aspetto molto interessante di questo approccio è che né il controller né il modello di vista Create
sono consapevoli delle regole di convalida effettive applicate o dei messaggi di errore specifici visualizzati. Le regole di convalida e le stringhe di errore vengono specificate solo nella classe Movie
. Le stesse regole di convalida vengono applicate automaticamente alla vista Edit
e ad altri modelli di vista eventualmente creati che modificano il modello.
Se necessario, è possibile modificare la logica di convalida in una posizione tramite l'aggiunta di attributi di convalida al modello, in questo esempio la classe Movie
. Non è necessario preoccuparsi dell'incoerenza delle diverse parti dell'applicazione con la modalità di applicazione delle regole perché tutta la logica di convalida verrà definita in un'unica posizione e usata ovunque. In questo modo il codice rimane molto pulito e facile da gestire e sviluppare. Il principio DRY sarà ampiamente rispettato.
Utilizzo degli attributi DataType
Aprire il Movie.cs
file ed esaminare la Movie
classe . Lo spazio dei nomi System.ComponentModel.DataAnnotations
fornisce gli attributi di formattazione oltre al set predefinito di attributi di convalida. È già stato applicato un valore di enumerazione DataType
ai campi della data di rilascio e del prezzo. Il codice seguente illustra le proprietà ReleaseDate
e Price
con l'attributo appropriato DataType
.
[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
[Range(1, 100)]
[DataType(DataType.Currency)]
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }
Gli DataType
attributi forniscono solo suggerimenti per il motore di visualizzazione per formattare i dati e fornire elementi/attributi, ad <a>
esempio per l'URL e <a href="mailto:EmailAddress.com">
per il messaggio di posta elettronica. È possibile usare l'attributo RegularExpression
per convalidare il formato dei dati. L'attributo DataType
viene usato per specificare un tipo di dati più specifico del tipo intrinseco del database; non si tratta di attributi di convalida. In questo caso si vuole solo tenere traccia della data, non dell'ora. L'enumerazione DataType
fornisce molti tipi di dati, ad esempio Data, Ora, Numero di telefono, Valuta, Indirizzo di posta elettronica e altro ancora. L'attributo DataType
può anche consentire all'applicazione di fornire automaticamente le funzionalità specifiche del tipo. Ad esempio, è possibile creare un collegamento mailto:
per DataType.EmailAddress
e fornire un selettore data per DataType.Date
nei browser che supportano HTML5. Gli attributi DataType
generano attributi data-
HTML5 (pronunciato data dash) supportati dai browser HTML5. Gli attributi DataType
non forniscono alcuna convalida.
DataType.Date
non specifica il formato della data visualizzata. Per impostazione predefinita, il campo dei dati viene visualizzato in base ai formati predefiniti per il valore CultureInfo
del server.
L'attributo DisplayFormat
viene usato per specificare in modo esplicito il formato della data:
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }
L'impostazione ApplyFormatInEditMode
specifica che la formattazione deve essere applicata anche quando il valore viene visualizzato in una casella di testo per la modifica. Questa scelta non è consigliabile per alcuni campi, ad esempio per i valori della valuta poiché non è opportuno che il simbolo di valuta sia inserito nella casella di testo per la modifica.
È possibile usare l'attributo DisplayFormat
da solo, ma in genere è consigliabile usare l'attributo DataType
. L'attributo DataType
fornisce la semantica dei dati anziché la modalità di esecuzione del rendering in una schermata e fornisce i seguenti vantaggi che non si ottengono con DisplayFormat:
Il browser può abilitare le funzionalità HTML5, ad esempio visualizzare un controllo di calendario, il simbolo della valuta appropriato per le impostazioni locali, i collegamenti alla posta elettronica e così via.
Per impostazione predefinita, il browser eseguirà il rendering dei dati usando il formato corretto in base alle impostazioni locali del sistema.
L'attributo
DataType
consente di abilitare MVC in modo da scegliere il modello di campo corretto per il rendering dei dati (DisplayFormat
, se usato da solo, usa il modello di stringa).
Nota
La convalida jQuery non funziona con l'attributo Range
e con DateTime
. Ad esempio, il codice seguente visualizzerà sempre un errore di convalida sul lato client, anche quando la data è compreso nell'intervallo specificato:
[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]
È necessario disabilitare la convalida della data jQuery per usare l'attributo Range
con DateTime
. In genere non è consigliabile compilare date reali nei modelli, quindi l'uso dell'attributo Range
e di DateTime
è sconsigliato.
Il codice seguente illustra la combinazione di attributi in una sola riga:
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace MvcMovie.Models;
public class Movie
{
public int Id { get; set; }
[StringLength(60, MinimumLength = 3)]
public string Title { get; set; }
[Display(Name = "Release Date"), DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$"), Required, StringLength(30)]
public string Genre { get; set; }
[Range(1, 100), DataType(DataType.Currency)]
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$"), StringLength(5)]
public string Rating { get; set; }
}
Nella parte successiva della serie viene esaminata l'app e vengono apportati alcuni miglioramenti ai metodi Details
e Delete
generati automaticamente.
Risorse aggiuntive
Contenuto della sezione:
- La logica di convalida viene aggiunta al modello
Movie
. - Si verifica che le regole di convalida vengano applicate ogni volta che un utente crea o modifica un film.
Rispetto del principio DRY
Uno dei principi di progettazione MVC è DRY ("Don't Repeat Yourself"). ASP.NET Core MVC promuove la specifica delle funzionalità o del comportamento una sola volta, con successiva applicazione ovunque in un'app. In questo modo si riduce la quantità di codice che è necessario scrivere e si rende il codice meno soggetto a errori, più semplice da testare e gestire.
Il supporto della convalida fornito da MVC ed Entity Framework Core Code First è un valido esempio pratico del principio DRY. È possibile specificare in modo dichiarativo le regole di convalida in un'unica posizione (nella classe del modello) e le regole vengono applicate ovunque nell'app.
Aggiungere regole di convalida al modello movie
Lo spazio dei nomi DataAnnotations offre un set di attributi di convalida predefiniti che vengono applicati in modo dichiarativo a una classe o una proprietà. DataAnnotations contiene anche gli attributi di formattazione come DataType
che guidano nella formattazione e non offrono alcuna convalida.
Aggiornare la classe Movie
per poter sfruttare gli attributi di convalida Required
, StringLength
, RegularExpression
e Range
predefiniti.
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace MvcMovie.Models
{
public class Movie
{
public int Id { get; set; }
[StringLength(60, MinimumLength = 3)]
[Required]
public string? Title { get; set; }
[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
[Range(1, 100)]
[DataType(DataType.Currency)]
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$")]
[Required]
[StringLength(30)]
public string? Genre { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$")]
[StringLength(5)]
[Required]
public string? Rating { get; set; }
}
}
Gli attributi di convalida specificano il comportamento da implementare nelle proprietà del modello a cui vengono applicati:
Gli attributi
Required
eMinimumLength
indicano che una proprietà deve avere un valore, ma nulla impedisce all'utente di inserire spazi vuoti per soddisfare questa convalida.L'attributo
RegularExpression
viene usato per limitare i caratteri che possono essere inseriti. Nel codice precedente "Genre":- Deve includere solo lettere.
- La prima lettera deve essere maiuscola. Gli spazi vuoti sono consentiti mentre i numeri e i caratteri speciali non sono consentiti.
RegularExpression
"Rating":- Richiede che il primo carattere sia una lettera maiuscola.
- Consente i caratteri speciali e i numeri negli spazi successivi. "PG-13" è valido per una classificazione, ma non per "Genre".
L'attributo
Range
vincola un valore all'interno di un intervallo specificato.L'attributo
StringLength
consente di impostare la lunghezza massima di una proprietà stringa e, facoltativamente, la lunghezza minima.I tipi di valore, ad esempio
decimal
,int
,float
eDateTime
, sono intrinsecamente necessari e non richiedono l'attributo[Required]
.
L'applicazione automatica di regole di convalida da ASP.NET Core è utile per rendere un'app più solida. In questo modo inoltre non è possibile omettere la convalida di un elemento e quindi inserire involontariamente dati errati nel database.
Interfaccia utente dell'errore di convalida
Eseguire l'app e passare al controller di film.
Selezionare il collegamento Crea nuovo per aggiungere un nuovo film. Completare il modulo con alcuni valori non validi. Non appena la convalida del lato client jQuery rileva l'errore, viene visualizzato un messaggio di errore.
Nota
È possibile che non si riesca a immettere virgole decimali nel campo. Per supportare la convalida jQuery per impostazioni locali diverse dall'inglese che usano la virgola (",") come separatore decimale e per formati di data diversi da quello dell'inglese degli Stati Uniti, è necessario eseguire alcuni passaggi per globalizzare l'app. Per istruzioni sull'aggiunta di una virgola decimale, vedere questo commento di GitHub 4076 .
Si noti come il modulo ha eseguito automaticamente il rendering di un messaggio di errore di convalida appropriato in ogni campo contenente un valore non valido. Gli errori vengono applicati sia sul lato client (utilizzo di JavaScript e jQuery) sia sul lato server (nel caso di un utente con JavaScript disabilitato).
Un vantaggio significativo è che non è necessario modificare una singola riga di codice nella MoviesController
classe o nella Create.cshtml
visualizzazione per abilitare questa interfaccia utente di convalida. Il controller e le viste creati in una fase precedente di questa esercitazione hanno selezionato automaticamente le regole di convalida specificate usando gli attributi di convalida delle proprietà della classe Movie
del modello. Eseguire il test della convalida usando il metodo di azione Edit
e viene applicata la stessa convalida.
I dati del modulo non vengono inviati al server fino a quando non sono più presenti errori di convalida sul lato client. È possibile verificare questa condizione inserendo un punto di interruzione nel metodo HTTP Post
usando lo strumento Fiddler o gli strumenti di sviluppo F12.
Funzionamento della convalida
Ci si potrebbe chiedere come la convalida dell'interfaccia utente sia stata generata senza aggiornamenti al codice nel controller o nelle viste. Il codice seguente mostra i due metodi Create
.
// GET: Movies/Create
public IActionResult Create()
{
return View();
}
// POST: Movies/Create
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
if (ModelState.IsValid)
{
_context.Add(movie);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(movie);
}
Il primo metodo di azione (HTTP GET) Create
visualizza il modulo di creazione iniziale. La seconda versione ([HttpPost]
) gestisce l'invio del modulo. Il secondo metodo Create
(la versione [HttpPost]
) chiama ModelState.IsValid
per verificare se esistono errori di convalida per il film. La chiamata a questo metodo valuta tutti gli attributi di convalida applicati all'oggetto. Se l'oggetto presenta errori di convalida, il metodo Create
visualizza di nuovo il modulo. Se non sono presenti errori, il metodo salva il nuovo film nel database. Nell'esempio del film, il modulo non viene inviato al server quando vengono rilevati errori di convalida sul lato client; il secondo metodo Create
non viene mai chiamato quando sono presenti errori di convalida sul lato client. Se si disabilita JavaScript nel browser, la convalida sul lato client viene disabilitata ed è possibile testare ModelState.IsValid
del metodo Create
HTTP POST rilevando eventuali errori di convalida.
È possibile impostare un punto di interruzione nel metodo [HttpPost] Create
e verificare che il metodo non venga mai chiamato, la convalida sul lato client non invierà i dati del modulo in caso di rilevamento di errori di convalida. Se si disabilita JavaScript nel browser, quindi si invia il modulo con errori, verrà raggiunto il punto di interruzione. Si ottiene comunque la convalida completa senza JavaScript.
L'immagine seguente mostra come disabilitare JavaScript nel browser Firefox.
La figura seguente illustra come disabilitare JavaScript nel browser Chrome.
Dopo avere disabilitato JavaScript, inviare i dati non validi e procedere con il debugger.
Una parte del Create.cshtml
modello di visualizzazione è illustrata nel markup seguente:
<h4>Movie</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Title" class="control-label"></label>
<input asp-for="Title" class="form-control" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
@*Markup removed for brevity.*@
Il markup precedente viene usato dai metodi di azione per visualizzare il modulo iniziale e per visualizzarlo nuovamente in caso di errore.
L'helper tag di input usa gli attributi DataAnnotations e produce gli attributi HTML necessari per la convalida jQuery sul lato client. L'helper tag di convalida visualizza gli errori di convalida. Per altre informazioni, vedere Convalida.
L'aspetto molto interessante di questo approccio è che né il controller né il modello di vista Create
sono consapevoli delle regole di convalida effettive applicate o dei messaggi di errore specifici visualizzati. Le regole di convalida e le stringhe di errore vengono specificate solo nella classe Movie
. Le stesse regole di convalida vengono applicate automaticamente alla vista Edit
e ad altri modelli di vista eventualmente creati che modificano il modello.
Se necessario, è possibile modificare la logica di convalida in una posizione tramite l'aggiunta di attributi di convalida al modello, in questo esempio la classe Movie
. Non è necessario preoccuparsi dell'incoerenza delle diverse parti dell'applicazione con la modalità di applicazione delle regole perché tutta la logica di convalida verrà definita in un'unica posizione e usata ovunque. In questo modo il codice rimane molto pulito e facile da gestire e sviluppare. Il principio DRY sarà ampiamente rispettato.
Utilizzo degli attributi DataType
Aprire il Movie.cs
file ed esaminare la Movie
classe . Lo spazio dei nomi System.ComponentModel.DataAnnotations
fornisce gli attributi di formattazione oltre al set predefinito di attributi di convalida. È già stato applicato un valore di enumerazione DataType
ai campi della data di rilascio e del prezzo. Il codice seguente illustra le proprietà ReleaseDate
e Price
con l'attributo appropriato DataType
.
[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
[Range(1, 100)]
[DataType(DataType.Currency)]
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }
Gli DataType
attributi forniscono solo suggerimenti per il motore di visualizzazione per formattare i dati e fornire elementi/attributi, ad <a>
esempio per l'URL e <a href="mailto:EmailAddress.com">
per il messaggio di posta elettronica. È possibile usare l'attributo RegularExpression
per convalidare il formato dei dati. L'attributo DataType
viene usato per specificare un tipo di dati più specifico del tipo intrinseco del database; non si tratta di attributi di convalida. In questo caso si vuole solo tenere traccia della data, non dell'ora. L'enumerazione DataType
fornisce molti tipi di dati, ad esempio Data, Ora, Numero di telefono, Valuta, Indirizzo di posta elettronica e altro ancora. L'attributo DataType
può anche consentire all'applicazione di fornire automaticamente le funzionalità specifiche del tipo. Ad esempio, è possibile creare un collegamento mailto:
per DataType.EmailAddress
e fornire un selettore data per DataType.Date
nei browser che supportano HTML5. Gli attributi DataType
generano attributi data-
HTML5 (pronunciato data dash) supportati dai browser HTML5. Gli attributi DataType
non forniscono alcuna convalida.
DataType.Date
non specifica il formato della data visualizzata. Per impostazione predefinita, il campo dei dati viene visualizzato in base ai formati predefiniti per il valore CultureInfo
del server.
L'attributo DisplayFormat
viene usato per specificare in modo esplicito il formato della data:
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }
L'impostazione ApplyFormatInEditMode
specifica che la formattazione deve essere applicata anche quando il valore viene visualizzato in una casella di testo per la modifica. Questa scelta non è consigliabile per alcuni campi, ad esempio per i valori della valuta poiché non è opportuno che il simbolo di valuta sia inserito nella casella di testo per la modifica.
È possibile usare l'attributo DisplayFormat
da solo, ma in genere è consigliabile usare l'attributo DataType
. L'attributo DataType
fornisce la semantica dei dati anziché la modalità di esecuzione del rendering in una schermata e fornisce i seguenti vantaggi che non si ottengono con DisplayFormat:
Il browser può abilitare le funzionalità HTML5, ad esempio visualizzare un controllo di calendario, il simbolo della valuta appropriato per le impostazioni locali, i collegamenti alla posta elettronica e così via.
Per impostazione predefinita, il browser eseguirà il rendering dei dati usando il formato corretto in base alle impostazioni locali del sistema.
L'attributo
DataType
consente di abilitare MVC in modo da scegliere il modello di campo corretto per il rendering dei dati (DisplayFormat
, se usato da solo, usa il modello di stringa).
Nota
La convalida jQuery non funziona con l'attributo Range
e con DateTime
. Ad esempio, il codice seguente visualizzerà sempre un errore di convalida sul lato client, anche quando la data è compreso nell'intervallo specificato:
[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]
È necessario disabilitare la convalida della data jQuery per usare l'attributo Range
con DateTime
. In genere non è consigliabile compilare date reali nei modelli, quindi l'uso dell'attributo Range
e di DateTime
è sconsigliato.
Il codice seguente illustra la combinazione di attributi in una sola riga:
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace MvcMovie.Models
{
public class Movie
{
public int Id { get; set; }
[StringLength(60, MinimumLength = 3)]
public string Title { get; set; }
[Display(Name = "Release Date"), DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$"), Required, StringLength(30)]
public string Genre { get; set; }
[Range(1, 100), DataType(DataType.Currency)]
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$"), StringLength(5)]
public string Rating { get; set; }
}
}
Nella parte successiva della serie viene esaminata l'app e vengono apportati alcuni miglioramenti ai metodi Details
e Delete
generati automaticamente.
Risorse aggiuntive
Contenuto della sezione:
- La logica di convalida viene aggiunta al modello
Movie
. - Si verifica che le regole di convalida vengano applicate ogni volta che un utente crea o modifica un film.
Rispetto del principio DRY
Uno dei principi di progettazione MVC è DRY ("Don't Repeat Yourself"). ASP.NET Core MVC promuove la specifica delle funzionalità o del comportamento una sola volta, con successiva applicazione ovunque in un'app. In questo modo si riduce la quantità di codice che è necessario scrivere e si rende il codice meno soggetto a errori, più semplice da testare e gestire.
Il supporto della convalida fornito da MVC ed Entity Framework Core Code First è un valido esempio pratico del principio DRY. È possibile specificare in modo dichiarativo le regole di convalida in un'unica posizione (nella classe del modello) e le regole vengono applicate ovunque nell'app.
Aggiungere regole di convalida al modello movie
Lo spazio dei nomi DataAnnotations offre un set di attributi di convalida predefiniti che vengono applicati in modo dichiarativo a una classe o una proprietà. DataAnnotations contiene anche gli attributi di formattazione come DataType
che guidano nella formattazione e non offrono alcuna convalida.
Aggiornare la classe Movie
per poter sfruttare gli attributi di convalida Required
, StringLength
, RegularExpression
e Range
predefiniti.
public class Movie
{
public int Id { get; set; }
[StringLength(60, MinimumLength = 3)]
[Required]
public string Title { get; set; }
[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
[Range(1, 100)]
[DataType(DataType.Currency)]
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$")]
[Required]
[StringLength(30)]
public string Genre { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$")]
[StringLength(5)]
[Required]
public string Rating { get; set; }
}
Gli attributi di convalida specificano il comportamento da implementare nelle proprietà del modello a cui vengono applicati:
Gli attributi
Required
eMinimumLength
indicano che una proprietà deve avere un valore, ma nulla impedisce all'utente di inserire spazi vuoti per soddisfare questa convalida.L'attributo
RegularExpression
viene usato per limitare i caratteri che possono essere inseriti. Nel codice precedente "Genre":- Deve includere solo lettere.
- La prima lettera deve essere maiuscola. Gli spazi vuoti sono consentiti, mentre i numeri e i caratteri speciali non sono consentiti.
RegularExpression
"Rating":- Richiede che il primo carattere sia una lettera maiuscola.
- Consente i caratteri speciali e i numeri negli spazi successivi. "PG-13" è valido per una classificazione, ma non per "Genre".
L'attributo
Range
vincola un valore all'interno di un intervallo specificato.L'attributo
StringLength
consente di impostare la lunghezza massima di una proprietà stringa e, facoltativamente, la lunghezza minima.I tipi di valore, ad esempio
decimal
,int
,float
eDateTime
, sono intrinsecamente necessari e non richiedono l'attributo[Required]
.
L'applicazione automatica di regole di convalida da ASP.NET Core è utile per rendere un'app più solida. In questo modo inoltre non è possibile omettere la convalida di un elemento e quindi inserire involontariamente dati errati nel database.
Interfaccia utente dell'errore di convalida
Eseguire l'app e passare al controller di film.
Toccare il collegamento Crea nuovo per aggiungere un nuovo film. Completare il modulo con alcuni valori non validi. Non appena la convalida del lato client jQuery rileva l'errore, viene visualizzato un messaggio di errore.
Nota
È possibile che non si riesca a immettere virgole decimali nel campo. Per supportare la convalida jQuery per impostazioni locali diverse dall'inglese che usano la virgola (",") come separatore decimale e per formati di data diversi da quello dell'inglese degli Stati Uniti, è necessario eseguire alcuni passaggi per globalizzare l'app. Per istruzioni sull'aggiunta di una virgola decimale, vedere questo commento di GitHub 4076 .
Si noti come il modulo ha eseguito automaticamente il rendering di un messaggio di errore di convalida appropriato in ogni campo contenente un valore non valido. Gli errori vengono applicati sia sul lato client (utilizzo di JavaScript e jQuery) sia sul lato server (nel caso di un utente con JavaScript disabilitato).
Un vantaggio significativo è che non è necessario modificare una singola riga di codice nella MoviesController
classe o nella Create.cshtml
visualizzazione per abilitare questa interfaccia utente di convalida. Il controller e le viste creati in una fase precedente di questa esercitazione hanno selezionato automaticamente le regole di convalida specificate usando gli attributi di convalida delle proprietà della classe Movie
del modello. Eseguire il test della convalida usando il metodo di azione Edit
e viene applicata la stessa convalida.
I dati del modulo non vengono inviati al server fino a quando non sono più presenti errori di convalida sul lato client. È possibile verificare questa condizione inserendo un punto di interruzione nel metodo HTTP Post
usando lo strumento Fiddler o gli strumenti di sviluppo F12.
Funzionamento della convalida
Ci si potrebbe chiedere come la convalida dell'interfaccia utente sia stata generata senza aggiornamenti al codice nel controller o nelle viste. Il codice seguente mostra i due metodi Create
.
// GET: Movies/Create
public IActionResult Create()
{
return View();
}
// POST: Movies/Create
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(
[Bind("ID,Title,ReleaseDate,Genre,Price, Rating")] Movie movie)
{
if (ModelState.IsValid)
{
_context.Add(movie);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(movie);
}
Il primo metodo di azione (HTTP GET) Create
visualizza il modulo di creazione iniziale. La seconda versione ([HttpPost]
) gestisce l'invio del modulo. Il secondo metodo Create
(la versione [HttpPost]
) chiama ModelState.IsValid
per verificare se esistono errori di convalida per il film. La chiamata a questo metodo valuta tutti gli attributi di convalida applicati all'oggetto. Se l'oggetto presenta errori di convalida, il metodo Create
visualizza di nuovo il modulo. Se non sono presenti errori, il metodo salva il nuovo film nel database. Nell'esempio del film, il modulo non viene inviato al server quando vengono rilevati errori di convalida sul lato client; il secondo metodo Create
non viene mai chiamato quando sono presenti errori di convalida sul lato client. Se si disabilita JavaScript nel browser, la convalida sul lato client viene disabilitata ed è possibile testare ModelState.IsValid
del metodo Create
HTTP POST rilevando eventuali errori di convalida.
È possibile impostare un punto di interruzione nel metodo [HttpPost] Create
e verificare che il metodo non venga mai chiamato, la convalida sul lato client non invierà i dati del modulo in caso di rilevamento di errori di convalida. Se si disabilita JavaScript nel browser, quindi si invia il modulo con errori, verrà raggiunto il punto di interruzione. Si ottiene comunque la convalida completa senza JavaScript.
L'immagine seguente mostra come disabilitare JavaScript nel browser Firefox.
La figura seguente illustra come disabilitare JavaScript nel browser Chrome.
Dopo avere disabilitato JavaScript, inviare i dati non validi e procedere con il debugger.
La parte del modello di Create.cshtml
visualizzazione è illustrata nel markup seguente:
<h4>Movie</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Title" class="control-label"></label>
<input asp-for="Title" class="form-control" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
@*Markup removed for brevity.*@
Il markup precedente viene usato dai metodi di azione per visualizzare il modulo iniziale e per visualizzarlo nuovamente in caso di errore.
L'helper tag di input usa gli attributi DataAnnotations e produce gli attributi HTML necessari per la convalida jQuery sul lato client. L'helper tag di convalida visualizza gli errori di convalida. Per altre informazioni, vedere Convalida.
L'aspetto molto interessante di questo approccio è che né il controller né il modello di vista Create
sono consapevoli delle regole di convalida effettive applicate o dei messaggi di errore specifici visualizzati. Le regole di convalida e le stringhe di errore vengono specificate solo nella classe Movie
. Le stesse regole di convalida vengono applicate automaticamente alla vista Edit
e ad altri modelli di vista eventualmente creati che modificano il modello.
Se necessario, è possibile modificare la logica di convalida in una posizione tramite l'aggiunta di attributi di convalida al modello, in questo esempio la classe Movie
. Non è necessario preoccuparsi dell'incoerenza delle diverse parti dell'applicazione con la modalità di applicazione delle regole perché tutta la logica di convalida verrà definita in un'unica posizione e usata ovunque. In questo modo il codice rimane molto pulito e facile da gestire e sviluppare. Il principio DRY sarà ampiamente rispettato.
Utilizzo degli attributi DataType
Aprire il Movie.cs
file ed esaminare la Movie
classe . Lo spazio dei nomi System.ComponentModel.DataAnnotations
fornisce gli attributi di formattazione oltre al set predefinito di attributi di convalida. È già stato applicato un valore di enumerazione DataType
ai campi della data di rilascio e del prezzo. Il codice seguente illustra le proprietà ReleaseDate
e Price
con l'attributo appropriato DataType
.
[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
[Range(1, 100)]
[DataType(DataType.Currency)]
public decimal Price { get; set; }
Gli attributi DataType
specificano solo gli hint per far sì che il motore di vista formatti i dati (e fornisca gli elementi/attributi, ad esempio <a>
per l'URL e <a href="mailto:EmailAddress.com">
per la posta elettronica). È possibile usare l'attributo RegularExpression
per convalidare il formato dei dati. L'attributo DataType
viene usato per specificare un tipo di dati più specifico del tipo intrinseco del database; non si tratta di attributi di convalida. In questo caso si vuole solo tenere traccia della data, non dell'ora. L'enumerazione DataType
fornisce molti tipi di dati, ad esempio Data, Ora, Numero di telefono, Valuta, Indirizzo di posta elettronica e altro ancora. L'attributo DataType
può anche consentire all'applicazione di fornire automaticamente le funzionalità specifiche del tipo. Ad esempio, è possibile creare un collegamento mailto:
per DataType.EmailAddress
e fornire un selettore data per DataType.Date
nei browser che supportano HTML5. Gli attributi DataType
generano attributi data-
HTML5 (pronunciato data dash) supportati dai browser HTML5. Gli attributi DataType
non forniscono alcuna convalida.
DataType.Date
non specifica il formato della data visualizzata. Per impostazione predefinita, il campo dei dati viene visualizzato in base ai formati predefiniti per il valore CultureInfo
del server.
L'attributo DisplayFormat
viene usato per specificare in modo esplicito il formato della data:
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }
L'impostazione ApplyFormatInEditMode
specifica che la formattazione deve essere applicata anche quando il valore viene visualizzato in una casella di testo per la modifica. Questa scelta non è consigliabile per alcuni campi, ad esempio per i valori della valuta poiché non è opportuno che il simbolo di valuta sia inserito nella casella di testo per la modifica.
È possibile usare l'attributo DisplayFormat
da solo, ma in genere è consigliabile usare l'attributo DataType
. L'attributo DataType
fornisce la semantica dei dati anziché la modalità di esecuzione del rendering in una schermata e fornisce i seguenti vantaggi che non si ottengono con DisplayFormat:
Il browser può abilitare le funzionalità HTML5, ad esempio visualizzare un controllo di calendario, il simbolo della valuta appropriato per le impostazioni locali, i collegamenti alla posta elettronica e così via.
Per impostazione predefinita, il browser eseguirà il rendering dei dati usando il formato corretto in base alle impostazioni locali del sistema.
L'attributo
DataType
consente di abilitare MVC in modo da scegliere il modello di campo corretto per il rendering dei dati (DisplayFormat
, se usato da solo, usa il modello di stringa).
Nota
La convalida jQuery non funziona con l'attributo Range
e con DateTime
. Ad esempio, il codice seguente visualizzerà sempre un errore di convalida sul lato client, anche quando la data è compreso nell'intervallo specificato:
[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]
È necessario disabilitare la convalida della data jQuery per usare l'attributo Range
con DateTime
. In genere non è consigliabile compilare date reali nei modelli, quindi l'uso dell'attributo Range
e di DateTime
è sconsigliato.
Il codice seguente illustra la combinazione di attributi in una sola riga:
public class Movie
{
public int Id { get; set; }
[StringLength(60, MinimumLength = 3)]
public string Title { get; set; }
[Display(Name = "Release Date"), DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$"), Required, StringLength(30)]
public string Genre { get; set; }
[Range(1, 100), DataType(DataType.Currency)]
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$"), StringLength(5)]
public string Rating { get; set; }
}
Nella parte successiva della serie viene esaminata l'app e vengono apportati alcuni miglioramenti ai metodi Details
e Delete
generati automaticamente.