Partie 9, ajouter la validation à une application MVC ASP.NET Core
Remarque
Ceci n’est pas la dernière version de cet article. Pour la version actuelle, consultez la version .NET 9 de cet article.
Avertissement
Cette version d’ASP.NET Core n’est plus prise en charge. Pour plus d’informations, consultez la stratégie de support .NET et .NET Core. Pour la version actuelle, consultez la version .NET 9 de cet article.
Important
Ces informations portent sur la préversion du produit, qui est susceptible d’être en grande partie modifié avant sa commercialisation. Microsoft n’offre aucune garantie, expresse ou implicite, concernant les informations fournies ici.
Pour la version actuelle, consultez la version .NET 9 de cet article.
Par Rick Anderson
Dans cette section :
- Une logique de validation est ajoutée au modèle
Movie
. - Vous vous assurez que les règles de validation sont appliquées chaque fois qu’un utilisateur crée ou modifie un film.
Ne vous répétez pas
L’un des principes de conception de MVC est « Ne vous répétez pas » (désigné par l’acronyme DRY, Don’t Repeat Yourself). ASP.NET Core MVC vous encourage à spécifier les fonctionnalités ou les comportements une seule fois, puis à utiliser la réflexion partout dans une application. Cela réduit la quantité de code à écrire, et rend le code que vous écrivez moins susceptible aux erreurs et plus facile à tester et à gérer.
La prise en charge de la validation fournie par MVC et Entity Framework Core est un bon exemple du principe DRY en action. Vous pouvez spécifier de façon déclarative des règles de validation à un seul emplacement (dans la classe de modèle), et les règles sont appliquées partout dans l’application.
Supprimer les données précédemment modifiées
À l’étape suivante, des règles de validation sont ajoutées qui n’autorisent pas les valeurs nulles.
Exécutez l’application, accédez à /Movies/Index
, supprimez tous les films listés et arrêtez l’application. L’application utilisera les données seed la prochaine fois qu’elle sera exécutée.
Ajouter des règles de validation au modèle de film
L’espace de noms DataAnnotations fournit un ensemble d’attributs de validation intégrés qui sont appliqués de façon déclarative à une classe ou à une propriété. DataAnnotations contient également des attributs de mise en forme, comme DataType
, qui aident à effectuer la mise en forme et ne fournissent aucune validation.
Mettez à jour la classe Movie
pour tirer parti des attributs de validation intégrés Required
, StringLength
, RegularExpression
, Range
et de l’attribut de mise en forme DataType
.
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; }
}
Les attributs de validation spécifient le comportement que vous souhaitez appliquer sur les propriétés du modèle sur lesquels ils sont appliqués :
Les attributs
Required
etMinimumLength
indiquent qu’une propriété doit avoir une valeur, mais rien n’empêche un utilisateur d’entrer un espace pour satisfaire à cette validation.L’attribut
RegularExpression
sert à limiter les caractères pouvant être entrés. Dans le code précédent, « Genre » :- Doit utiliser seulement des lettres.
- La première lettre doit être une majuscule. Les espaces blancs sont autorisés tandis que les nombres et les caractères spéciaux ne sont pas autorisés.
L’expression
RegularExpression
« Rating » :- Nécessite que le premier caractère soit une lettre majuscule.
- Autorise les caractères spéciaux et les chiffres aux emplacements qui suivent. « PG-13 » est valide pour une évaluation, mais échoue pour un « Genre ».
L’attribut
Range
limite une valeur à une plage spécifiée.L’attribut
StringLength
vous permet de définir la longueur maximale d’une propriété de chaîne, et éventuellement sa longueur minimale.Les types valeur (tels que
decimal
,int
,float
etDateTime
) sont obligatoires par nature et n’ont pas besoin de l’attribut[Required]
.
L’application automatique des règles de validation par ASP.NET Core permet d’accroître la fiabilité de votre application. Cela garantit également que vous n’oublierez pas de valider un élément et que vous n’autoriserez pas par inadvertance l’insertion de données incorrectes dans la base de données.
Interface utilisateur des erreurs de validation
Exécutez l’application et accédez au contrôleur Movies.
Sélectionnez le lien Créer nouveau pour ajouter un nouveau film. Remplissez le formulaire avec des valeurs non valides. Dès que la validation côté client jQuery détecte l’erreur, elle affiche un message d’erreur.
Notes
Vous ne pourrez peut-être pas entrer de virgules décimales dans les champs décimaux. Pour prendre en charge la validation jQuery pour les paramètres régionaux autres que l’anglais qui utilisent une virgule (« , ») comme décimale et des formats de date autres que l’anglais des États-Unis, vous devez effectuer des étapes pour localiser votre application. Consultez ce commentaire GitHub 4076 pour savoir comment ajouter une virgule décimale.
Notez que le formulaire a affiché automatiquement un message d’erreur de validation approprié dans chaque champ contenant une valeur non valide. Les erreurs sont appliquées à la fois côté client (à l’aide de JavaScript et jQuery) et côté serveur (au cas où un utilisateur aurait désactivé JavaScript).
L’un des principaux avantages est que vous n’avez pas eu à changer une seule ligne de code dans la classe MoviesController
ou dans la vue Create.cshtml
pour activer cette interface utilisateur de validation. Le contrôleur et les vues créées précédemment dans ce didacticiel ont détecté les règles de validation que vous avez spécifiées à l’aide des attributs de validation sur les propriétés de la classe de modèle Movie
. Testez la validation à l’aide de la méthode d’action Edit
. La même validation est appliquée.
Les données de formulaire ne sont pas envoyées au serveur tant qu’il y a des erreurs de validation côté client. Vous pouvez vérifier cela en plaçant un point d’arrêt dans la méthode HTTP Post
, en utilisant l’outil Fiddler ou à l’aide des Outils de développement F12.
Fonctionnement de la validation
Vous vous demandez peut-être comment l’interface utilisateur de validation a été générée sans aucune mise à jour du code dans le contrôleur ou dans les vues. Le code suivant montre les deux méthodes 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);
}
La première méthode d’action (HTTP GET) Create
affiche le formulaire de création initial. La deuxième version ([HttpPost]
) gère la publication de formulaire. La seconde méthode Create
(la version [HttpPost]
) appelle ModelState.IsValid
pour vérifier si le film a des erreurs de validation. L’appel de cette méthode évalue tous les attributs de validation qui ont été appliqués à l’objet. Si l’objet comporte des erreurs de validation, la méthode Create
réaffiche le formulaire. S’il n’y a pas d’erreur, la méthode enregistre le nouveau film dans la base de données. Dans notre exemple de film, le formulaire n’est pas publié sur le serveur quand des erreurs de validation sont détectées côté client ; la seconde méthode Create
n’est jamais appelée quand il y a des erreurs de validation côté client. Si vous désactivez JavaScript dans votre navigateur, la validation client est désactivée et vous pouvez tester la méthode Create
HTTP POST ModelState.IsValid
pour détecter les erreurs de validation.
Vous pouvez définir un point d’arrêt dans la méthode [HttpPost] Create
et vérifier que la méthode n’est jamais appelée. La validation côté client n’enverra pas les données du formulaire quand des erreurs de validation seront détectées. Si vous désactivez JavaScript dans votre navigateur et que vous envoyez ensuite le formulaire avec des erreurs, le point d’arrêt sera atteint. Vous bénéficiez toujours d’une validation complète sans JavaScript.
L’illustration suivante montre comment désactiver JavaScript dans le navigateur Firefox.
L’illustration suivante montre comment désactiver JavaScript dans le navigateur Chrome.
Après la désactivation de JavaScript, publiez les données non valides et parcourez le débogueur.
Une partie du modèle d’affichage Create.cshtml
est indiquée dans le balisage suivant :
<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.*@
Le balisage précédent est utilisé par les méthodes d’action pour afficher le formulaire initial et pour le réafficher en cas d’erreur.
Le Tag Helper Input utilise les attributs DataAnnotations et produit les attributs HTML nécessaires à la validation jQuery côté client. Le Tag Helper Validation affiche les erreurs de validation. Pour plus d’informations, consultez Validation.
Le grand avantage de cette approche est que ni le contrôleur ni le modèle de vue Create
ne savent rien des règles de validation appliquées ou des messages d’erreur affichés. Les règles de validation et les chaînes d’erreur sont spécifiées uniquement dans la classe Movie
. Ces mêmes règles de validation sont automatiquement appliquées à la vue Edit
et à tous les autres modèles de vues que vous pouvez créer et qui modifient votre modèle.
Quand vous devez changer la logique de validation, vous pouvez le faire à un seul endroit en ajoutant des attributs de validation au modèle (dans cet exemple, la classe Movie
). Vous n’aurez pas à vous soucier des différentes parties de l’application qui pourraient être incohérentes avec la façon dont les règles sont appliquées. Toute la logique de validation sera définie à un seul emplacement et utilisée partout. Le code est ainsi très propre, facile à mettre à jour et évolutif. Et cela signifie que vous respecterez entièrement le principe DRY.
Utilisation d’attributs DataType
Ouvrez le fichier Movie.cs
et examinez la classe Movie
. L’espace de noms System.ComponentModel.DataAnnotations
fournit des attributs de mise en forme en plus de l’ensemble intégré d’attributs de validation. Nous avons déjà appliqué une valeur d’énumération DataType
aux champs de date de sortie et de prix. Le code suivant illustre les propriétés ReleaseDate
et Price
avec l’attribut DataType
approprié.
[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; }
Les attributs DataType
fournissent uniquement des indices permettant au moteur de vue de mettre en forme les données (et fournissent des éléments/attributs tels que <a>
pour les URL et <a href="mailto:EmailAddress.com">
pour l’e-mail). Vous pouvez utiliser l’attribut RegularExpression
pour valider le format des données. L’attribut DataType
sert à spécifier un type de données qui est plus spécifique que le type intrinsèque de la base de données ; il ne s’agit pas d’un attribut de validation. Dans le cas présent, nous voulons uniquement effectuer le suivi de la date, et non de l’heure. L’énumération DataType
fournit de nombreux types de données, telles que Date, Time, PhoneNumber, Currency ou EmailAddress. L’attribut DataType
peut également permettre à l’application de fournir automatiquement des fonctionnalités propres au type. Par exemple, vous pouvez créer un lien mailto:
pour DataType.EmailAddress
, et vous pouvez fournir un sélecteur de date pour DataType.Date
dans les navigateurs qui prennent en charge HTML5. Les attributs DataType
émettent des attributs HTML 5 data-
compréhensibles par les navigateurs HTML 5. Les attributs DataType
ne fournissent aucune validation.
DataType.Date
ne spécifie pas le format de la date qui s’affiche. Par défaut, le champ de données est affiché conformément aux formats par défaut basés sur le CultureInfo
du serveur.
L’attribut DisplayFormat
est utilisé pour spécifier explicitement le format de date :
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }
Le paramètre ApplyFormatInEditMode
indique que la mise en forme doit également être appliquée quand la valeur est affichée dans une zone de texte à des fins de modification. (Ceci peut ne pas être souhaitable pour certains champs ; par exemple, pour les valeurs monétaires, vous ne souhaiterez sans doute pas que le symbole monétaire figure dans la zone de texte.)
Vous pouvez utiliser l’attribut DisplayFormat
par lui-même, mais il est généralement préférable d’utiliser l’attribut DataType
. L’attribut DataType
donne la sémantique des données, plutôt que de décrire comment effectuer le rendu sur un écran, et il offre les avantages suivants dont vous ne bénéficiez pas avec DisplayFormat :
Le navigateur peut activer des fonctionnalités HTML5 (par exemple pour afficher un contrôle de calendrier, le symbole monétaire correspondant aux paramètres régionaux, des liens de messagerie, etc.).
Par défaut, le navigateur affiche les données à l’aide du format correspondant à vos paramètres régionaux.
L’attribut
DataType
peut permettre à MVC de choisir le modèle de champ correct pour afficher les données (DisplayFormat
, utilisé par lui-même, utilise le modèle de chaîne).
Notes
La validation jQuery ne fonctionne pas avec l’attribut Range
et DateTime
. Par exemple, le code suivant affiche toujours une erreur de validation côté client, même quand la date se trouve dans la plage spécifiée :
[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]
Vous devez désactiver la validation de date jQuery pour utiliser l’attribut Range
avec DateTime
. Il n’est généralement pas recommandé de compiler des dates dures dans vos modèles. Par conséquent, l’utilisation de l’attribut Range
et de DateTime
est déconseillée.
Le code suivant illustre la combinaison d’attributs sur une seule ligne :
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; }
}
Dans la partie suivante de la série, nous examinons l’application et nous apportons des améliorations aux méthodes Details
et Delete
générées automatiquement.
Ressources supplémentaires
Dans cette section :
- Une logique de validation est ajoutée au modèle
Movie
. - Vous vous assurez que les règles de validation sont appliquées chaque fois qu’un utilisateur crée ou modifie un film.
Ne vous répétez pas
L’un des principes de conception de MVC est « Ne vous répétez pas » (désigné par l’acronyme DRY, Don’t Repeat Yourself). ASP.NET Core MVC vous encourage à spécifier les fonctionnalités ou les comportements une seule fois, puis à utiliser la réflexion partout dans une application. Cela réduit la quantité de code à écrire, et rend le code que vous écrivez moins susceptible aux erreurs et plus facile à tester et à gérer.
La prise en charge de la validation fournie par MVC et Entity Framework Core Code First est un bon exemple du principe DRY en action. Vous pouvez spécifier de façon déclarative des règles de validation à un seul emplacement (dans la classe de modèle), et les règles sont appliquées partout dans l’application.
Supprimer les données précédemment modifiées
À l’étape suivante, des règles de validation sont ajoutées qui n’autorisent pas les valeurs nulles.
Exécutez l’application, accédez à /Movies/Index
, supprimez tous les films listés et arrêtez l’application. L’application utilisera les données seed la prochaine fois qu’elle sera exécutée.
Ajouter des règles de validation au modèle de film
L’espace de noms DataAnnotations fournit un ensemble d’attributs de validation intégrés qui sont appliqués de façon déclarative à une classe ou à une propriété. DataAnnotations contient également des attributs de mise en forme, comme DataType
, qui aident à effectuer la mise en forme et ne fournissent aucune validation.
Mettez à jour la classe Movie
pour tirer parti des attributs de validation intégrés Required
, StringLength
, RegularExpression
, Range
et de l’attribut de mise en forme DataType
.
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; }
}
Les attributs de validation spécifient le comportement que vous souhaitez appliquer sur les propriétés du modèle sur lesquels ils sont appliqués :
Les attributs
Required
etMinimumLength
indiquent qu’une propriété doit avoir une valeur, mais rien n’empêche un utilisateur d’entrer un espace pour satisfaire à cette validation.L’attribut
RegularExpression
sert à limiter les caractères pouvant être entrés. Dans le code précédent, « Genre » :- Doit utiliser seulement des lettres.
- La première lettre doit être une majuscule. Les espaces blancs sont autorisés tandis que les nombres et les caractères spéciaux ne sont pas autorisés.
L’expression
RegularExpression
« Rating » :- Nécessite que le premier caractère soit une lettre majuscule.
- Autorise les caractères spéciaux et les chiffres aux emplacements qui suivent. « PG-13 » est valide pour une évaluation, mais échoue pour un « Genre ».
L’attribut
Range
limite une valeur à une plage spécifiée.L’attribut
StringLength
vous permet de définir la longueur maximale d’une propriété de chaîne, et éventuellement sa longueur minimale.Les types valeur (tels que
decimal
,int
,float
etDateTime
) sont obligatoires par nature et n’ont pas besoin de l’attribut[Required]
.
L’application automatique des règles de validation par ASP.NET Core permet d’accroître la fiabilité de votre application. Cela garantit également que vous n’oublierez pas de valider un élément et que vous n’autoriserez pas par inadvertance l’insertion de données incorrectes dans la base de données.
Interface utilisateur des erreurs de validation
Exécutez l’application et accédez au contrôleur Movies.
Sélectionnez le lien Créer nouveau pour ajouter un nouveau film. Remplissez le formulaire avec des valeurs non valides. Dès que la validation côté client jQuery détecte l’erreur, elle affiche un message d’erreur.
Notes
Vous ne pourrez peut-être pas entrer de virgules décimales dans les champs décimaux. Pour prendre en charge la validation jQuery pour les paramètres régionaux autres que l’anglais qui utilisent une virgule (« , ») comme décimale et des formats de date autres que l’anglais des États-Unis, vous devez effectuer des étapes pour localiser votre application. Consultez ce commentaire GitHub 4076 pour savoir comment ajouter une virgule décimale.
Notez que le formulaire a affiché automatiquement un message d’erreur de validation approprié dans chaque champ contenant une valeur non valide. Les erreurs sont appliquées à la fois côté client (à l’aide de JavaScript et jQuery) et côté serveur (au cas où un utilisateur aurait désactivé JavaScript).
L’un des principaux avantages est que vous n’avez pas eu à changer une seule ligne de code dans la classe MoviesController
ou dans la vue Create.cshtml
pour activer cette interface utilisateur de validation. Le contrôleur et les vues créées précédemment dans ce didacticiel ont détecté les règles de validation que vous avez spécifiées à l’aide des attributs de validation sur les propriétés de la classe de modèle Movie
. Testez la validation à l’aide de la méthode d’action Edit
. La même validation est appliquée.
Les données de formulaire ne sont pas envoyées au serveur tant qu’il y a des erreurs de validation côté client. Vous pouvez vérifier cela en plaçant un point d’arrêt dans la méthode HTTP Post
, en utilisant l’outil Fiddler ou à l’aide des Outils de développement F12.
Fonctionnement de la validation
Vous vous demandez peut-être comment l’interface utilisateur de validation a été générée sans aucune mise à jour du code dans le contrôleur ou dans les vues. Le code suivant montre les deux méthodes 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);
}
La première méthode d’action (HTTP GET) Create
affiche le formulaire de création initial. La deuxième version ([HttpPost]
) gère la publication de formulaire. La seconde méthode Create
(la version [HttpPost]
) appelle ModelState.IsValid
pour vérifier si le film a des erreurs de validation. L’appel de cette méthode évalue tous les attributs de validation qui ont été appliqués à l’objet. Si l’objet comporte des erreurs de validation, la méthode Create
réaffiche le formulaire. S’il n’y a pas d’erreur, la méthode enregistre le nouveau film dans la base de données. Dans notre exemple de film, le formulaire n’est pas publié sur le serveur quand des erreurs de validation sont détectées côté client ; la seconde méthode Create
n’est jamais appelée quand il y a des erreurs de validation côté client. Si vous désactivez JavaScript dans votre navigateur, la validation client est désactivée et vous pouvez tester la méthode Create
HTTP POST ModelState.IsValid
pour détecter les erreurs de validation.
Vous pouvez définir un point d’arrêt dans la méthode [HttpPost] Create
et vérifier que la méthode n’est jamais appelée. La validation côté client n’enverra pas les données du formulaire quand des erreurs de validation seront détectées. Si vous désactivez JavaScript dans votre navigateur et que vous envoyez ensuite le formulaire avec des erreurs, le point d’arrêt sera atteint. Vous bénéficiez toujours d’une validation complète sans JavaScript.
L’illustration suivante montre comment désactiver JavaScript dans le navigateur Firefox.
L’illustration suivante montre comment désactiver JavaScript dans le navigateur Chrome.
Après la désactivation de JavaScript, publiez les données non valides et parcourez le débogueur.
Une partie du modèle d’affichage Create.cshtml
est indiquée dans le balisage suivant :
<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.*@
Le balisage précédent est utilisé par les méthodes d’action pour afficher le formulaire initial et pour le réafficher en cas d’erreur.
Le Tag Helper Input utilise les attributs DataAnnotations et produit les attributs HTML nécessaires à la validation jQuery côté client. Le Tag Helper Validation affiche les erreurs de validation. Pour plus d’informations, consultez Validation.
Le grand avantage de cette approche est que ni le contrôleur ni le modèle de vue Create
ne savent rien des règles de validation appliquées ou des messages d’erreur affichés. Les règles de validation et les chaînes d’erreur sont spécifiées uniquement dans la classe Movie
. Ces mêmes règles de validation sont automatiquement appliquées à la vue Edit
et à tous les autres modèles de vues que vous pouvez créer et qui modifient votre modèle.
Quand vous devez changer la logique de validation, vous pouvez le faire à un seul endroit en ajoutant des attributs de validation au modèle (dans cet exemple, la classe Movie
). Vous n’aurez pas à vous soucier des différentes parties de l’application qui pourraient être incohérentes avec la façon dont les règles sont appliquées. Toute la logique de validation sera définie à un seul emplacement et utilisée partout. Le code est ainsi très propre, facile à mettre à jour et évolutif. Et cela signifie que vous respecterez entièrement le principe DRY.
Utilisation d’attributs DataType
Ouvrez le fichier Movie.cs
et examinez la classe Movie
. L’espace de noms System.ComponentModel.DataAnnotations
fournit des attributs de mise en forme en plus de l’ensemble intégré d’attributs de validation. Nous avons déjà appliqué une valeur d’énumération DataType
aux champs de date de sortie et de prix. Le code suivant illustre les propriétés ReleaseDate
et Price
avec l’attribut DataType
approprié.
[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; }
Les attributs DataType
fournissent uniquement des indices permettant au moteur de vue de mettre en forme les données (et fournissent des éléments/attributs tels que <a>
pour les URL et <a href="mailto:EmailAddress.com">
pour l’e-mail). Vous pouvez utiliser l’attribut RegularExpression
pour valider le format des données. L’attribut DataType
sert à spécifier un type de données qui est plus spécifique que le type intrinsèque de la base de données ; il ne s’agit pas d’un attribut de validation. Dans le cas présent, nous voulons uniquement effectuer le suivi de la date, et non de l’heure. L’énumération DataType
fournit de nombreux types de données, telles que Date, Time, PhoneNumber, Currency ou EmailAddress. L’attribut DataType
peut également permettre à l’application de fournir automatiquement des fonctionnalités propres au type. Par exemple, vous pouvez créer un lien mailto:
pour DataType.EmailAddress
, et vous pouvez fournir un sélecteur de date pour DataType.Date
dans les navigateurs qui prennent en charge HTML5. Les attributs DataType
émettent des attributs HTML 5 data-
compréhensibles par les navigateurs HTML 5. Les attributs DataType
ne fournissent aucune validation.
DataType.Date
ne spécifie pas le format de la date qui s’affiche. Par défaut, le champ de données est affiché conformément aux formats par défaut basés sur le CultureInfo
du serveur.
L’attribut DisplayFormat
est utilisé pour spécifier explicitement le format de date :
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }
Le paramètre ApplyFormatInEditMode
indique que la mise en forme doit également être appliquée quand la valeur est affichée dans une zone de texte à des fins de modification. (Ceci peut ne pas être souhaitable pour certains champs ; par exemple, pour les valeurs monétaires, vous ne souhaiterez sans doute pas que le symbole monétaire figure dans la zone de texte.)
Vous pouvez utiliser l’attribut DisplayFormat
par lui-même, mais il est généralement préférable d’utiliser l’attribut DataType
. L’attribut DataType
donne la sémantique des données, plutôt que de décrire comment effectuer le rendu sur un écran, et il offre les avantages suivants dont vous ne bénéficiez pas avec DisplayFormat :
Le navigateur peut activer des fonctionnalités HTML5 (par exemple pour afficher un contrôle de calendrier, le symbole monétaire correspondant aux paramètres régionaux, des liens de messagerie, etc.).
Par défaut, le navigateur affiche les données à l’aide du format correspondant à vos paramètres régionaux.
L’attribut
DataType
peut permettre à MVC de choisir le modèle de champ correct pour afficher les données (DisplayFormat
, utilisé par lui-même, utilise le modèle de chaîne).
Notes
La validation jQuery ne fonctionne pas avec l’attribut Range
et DateTime
. Par exemple, le code suivant affiche toujours une erreur de validation côté client, même quand la date se trouve dans la plage spécifiée :
[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]
Vous devez désactiver la validation de date jQuery pour utiliser l’attribut Range
avec DateTime
. Il n’est généralement pas recommandé de compiler des dates dures dans vos modèles. Par conséquent, l’utilisation de l’attribut Range
et de DateTime
est déconseillée.
Le code suivant illustre la combinaison d’attributs sur une seule ligne :
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; }
}
Dans la partie suivante de la série, nous examinons l’application et nous apportons des améliorations aux méthodes Details
et Delete
générées automatiquement.
Ressources supplémentaires
Dans cette section :
- Une logique de validation est ajoutée au modèle
Movie
. - Vous vous assurez que les règles de validation sont appliquées chaque fois qu’un utilisateur crée ou modifie un film.
Ne vous répétez pas
L’un des principes de conception de MVC est « Ne vous répétez pas » (désigné par l’acronyme DRY, Don’t Repeat Yourself). ASP.NET Core MVC vous encourage à spécifier les fonctionnalités ou les comportements une seule fois, puis à utiliser la réflexion partout dans une application. Cela réduit la quantité de code à écrire, et rend le code que vous écrivez moins susceptible aux erreurs et plus facile à tester et à gérer.
La prise en charge de la validation fournie par MVC et Entity Framework Core Code First est un bon exemple du principe DRY en action. Vous pouvez spécifier de façon déclarative des règles de validation à un seul emplacement (dans la classe de modèle), et les règles sont appliquées partout dans l’application.
Ajouter des règles de validation au modèle de film
L’espace de noms DataAnnotations fournit un ensemble d’attributs de validation intégrés qui sont appliqués de façon déclarative à une classe ou à une propriété. DataAnnotations contient également des attributs de mise en forme, comme DataType
, qui aident à effectuer la mise en forme et ne fournissent aucune validation.
Mettez à jour la classe Movie
pour tirer parti des attributs de validation intégrés Required
, StringLength
, RegularExpression
, Range
et de l’attribut de mise en forme DataType
.
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; }
}
Les attributs de validation spécifient le comportement que vous souhaitez appliquer sur les propriétés du modèle sur lesquels ils sont appliqués :
Les attributs
Required
etMinimumLength
indiquent qu’une propriété doit avoir une valeur, mais rien n’empêche un utilisateur d’entrer un espace pour satisfaire à cette validation.L’attribut
RegularExpression
sert à limiter les caractères pouvant être entrés. Dans le code précédent, « Genre » :- Doit utiliser seulement des lettres.
- La première lettre doit être une majuscule. Les espaces blancs sont autorisés tandis que les nombres et les caractères spéciaux ne sont pas autorisés.
L’expression
RegularExpression
« Rating » :- Nécessite que le premier caractère soit une lettre majuscule.
- Autorise les caractères spéciaux et les chiffres aux emplacements qui suivent. « PG-13 » est valide pour une évaluation, mais échoue pour un « Genre ».
L’attribut
Range
limite une valeur à une plage spécifiée.L’attribut
StringLength
vous permet de définir la longueur maximale d’une propriété de chaîne, et éventuellement sa longueur minimale.Les types valeur (tels que
decimal
,int
,float
etDateTime
) sont obligatoires par nature et n’ont pas besoin de l’attribut[Required]
.
L’application automatique des règles de validation par ASP.NET Core permet d’accroître la fiabilité de votre application. Cela garantit également que vous n’oublierez pas de valider un élément et que vous n’autoriserez pas par inadvertance l’insertion de données incorrectes dans la base de données.
Interface utilisateur des erreurs de validation
Exécutez l’application et accédez au contrôleur Movies.
Sélectionnez le lien Créer nouveau pour ajouter un nouveau film. Remplissez le formulaire avec des valeurs non valides. Dès que la validation côté client jQuery détecte l’erreur, elle affiche un message d’erreur.
Notes
Vous ne pourrez peut-être pas entrer de virgules décimales dans les champs décimaux. Pour prendre en charge la validation jQuery pour les paramètres régionaux autres que l’anglais qui utilisent une virgule (« , ») comme décimale et des formats de date autres que l’anglais des États-Unis, vous devez effectuer des étapes pour localiser votre application. Consultez ce commentaire GitHub 4076 pour savoir comment ajouter une virgule décimale.
Notez que le formulaire a affiché automatiquement un message d’erreur de validation approprié dans chaque champ contenant une valeur non valide. Les erreurs sont appliquées à la fois côté client (à l’aide de JavaScript et jQuery) et côté serveur (au cas où un utilisateur aurait désactivé JavaScript).
L’un des principaux avantages est que vous n’avez pas eu à changer une seule ligne de code dans la classe MoviesController
ou dans la vue Create.cshtml
pour activer cette interface utilisateur de validation. Le contrôleur et les vues créées précédemment dans ce didacticiel ont détecté les règles de validation que vous avez spécifiées à l’aide des attributs de validation sur les propriétés de la classe de modèle Movie
. Testez la validation à l’aide de la méthode d’action Edit
. La même validation est appliquée.
Les données de formulaire ne sont pas envoyées au serveur tant qu’il y a des erreurs de validation côté client. Vous pouvez vérifier cela en plaçant un point d’arrêt dans la méthode HTTP Post
, en utilisant l’outil Fiddler ou à l’aide des Outils de développement F12.
Fonctionnement de la validation
Vous vous demandez peut-être comment l’interface utilisateur de validation a été générée sans aucune mise à jour du code dans le contrôleur ou dans les vues. Le code suivant montre les deux méthodes 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);
}
La première méthode d’action (HTTP GET) Create
affiche le formulaire de création initial. La deuxième version ([HttpPost]
) gère la publication de formulaire. La seconde méthode Create
(la version [HttpPost]
) appelle ModelState.IsValid
pour vérifier si le film a des erreurs de validation. L’appel de cette méthode évalue tous les attributs de validation qui ont été appliqués à l’objet. Si l’objet comporte des erreurs de validation, la méthode Create
réaffiche le formulaire. S’il n’y a pas d’erreur, la méthode enregistre le nouveau film dans la base de données. Dans notre exemple de film, le formulaire n’est pas publié sur le serveur quand des erreurs de validation sont détectées côté client ; la seconde méthode Create
n’est jamais appelée quand il y a des erreurs de validation côté client. Si vous désactivez JavaScript dans votre navigateur, la validation client est désactivée et vous pouvez tester la méthode Create
HTTP POST ModelState.IsValid
pour détecter les erreurs de validation.
Vous pouvez définir un point d’arrêt dans la méthode [HttpPost] Create
et vérifier que la méthode n’est jamais appelée. La validation côté client n’enverra pas les données du formulaire quand des erreurs de validation seront détectées. Si vous désactivez JavaScript dans votre navigateur et que vous envoyez ensuite le formulaire avec des erreurs, le point d’arrêt sera atteint. Vous bénéficiez toujours d’une validation complète sans JavaScript.
L’illustration suivante montre comment désactiver JavaScript dans le navigateur Firefox.
L’illustration suivante montre comment désactiver JavaScript dans le navigateur Chrome.
Après la désactivation de JavaScript, publiez les données non valides et parcourez le débogueur.
Une partie du modèle d’affichage Create.cshtml
est indiquée dans le balisage suivant :
<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.*@
Le balisage précédent est utilisé par les méthodes d’action pour afficher le formulaire initial et pour le réafficher en cas d’erreur.
Le Tag Helper Input utilise les attributs DataAnnotations et produit les attributs HTML nécessaires à la validation jQuery côté client. Le Tag Helper Validation affiche les erreurs de validation. Pour plus d’informations, consultez Validation.
Le grand avantage de cette approche est que ni le contrôleur ni le modèle de vue Create
ne savent rien des règles de validation appliquées ou des messages d’erreur affichés. Les règles de validation et les chaînes d’erreur sont spécifiées uniquement dans la classe Movie
. Ces mêmes règles de validation sont automatiquement appliquées à la vue Edit
et à tous les autres modèles de vues que vous pouvez créer et qui modifient votre modèle.
Quand vous devez changer la logique de validation, vous pouvez le faire à un seul endroit en ajoutant des attributs de validation au modèle (dans cet exemple, la classe Movie
). Vous n’aurez pas à vous soucier des différentes parties de l’application qui pourraient être incohérentes avec la façon dont les règles sont appliquées. Toute la logique de validation sera définie à un seul emplacement et utilisée partout. Le code est ainsi très propre, facile à mettre à jour et évolutif. Et cela signifie que vous respecterez entièrement le principe DRY.
Utilisation d’attributs DataType
Ouvrez le fichier Movie.cs
et examinez la classe Movie
. L’espace de noms System.ComponentModel.DataAnnotations
fournit des attributs de mise en forme en plus de l’ensemble intégré d’attributs de validation. Nous avons déjà appliqué une valeur d’énumération DataType
aux champs de date de sortie et de prix. Le code suivant illustre les propriétés ReleaseDate
et Price
avec l’attribut DataType
approprié.
[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; }
Les attributs DataType
fournissent uniquement des indices permettant au moteur de vue de mettre en forme les données (et fournissent des éléments/attributs tels que <a>
pour les URL et <a href="mailto:EmailAddress.com">
pour l’e-mail). Vous pouvez utiliser l’attribut RegularExpression
pour valider le format des données. L’attribut DataType
sert à spécifier un type de données qui est plus spécifique que le type intrinsèque de la base de données ; il ne s’agit pas d’un attribut de validation. Dans le cas présent, nous voulons uniquement effectuer le suivi de la date, et non de l’heure. L’énumération DataType
fournit de nombreux types de données, telles que Date, Time, PhoneNumber, Currency ou EmailAddress. L’attribut DataType
peut également permettre à l’application de fournir automatiquement des fonctionnalités propres au type. Par exemple, vous pouvez créer un lien mailto:
pour DataType.EmailAddress
, et vous pouvez fournir un sélecteur de date pour DataType.Date
dans les navigateurs qui prennent en charge HTML5. Les attributs DataType
émettent des attributs HTML 5 data-
compréhensibles par les navigateurs HTML 5. Les attributs DataType
ne fournissent aucune validation.
DataType.Date
ne spécifie pas le format de la date qui s’affiche. Par défaut, le champ de données est affiché conformément aux formats par défaut basés sur le CultureInfo
du serveur.
L’attribut DisplayFormat
est utilisé pour spécifier explicitement le format de date :
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }
Le paramètre ApplyFormatInEditMode
indique que la mise en forme doit également être appliquée quand la valeur est affichée dans une zone de texte à des fins de modification. (Ceci peut ne pas être souhaitable pour certains champs ; par exemple, pour les valeurs monétaires, vous ne souhaiterez sans doute pas que le symbole monétaire figure dans la zone de texte.)
Vous pouvez utiliser l’attribut DisplayFormat
par lui-même, mais il est généralement préférable d’utiliser l’attribut DataType
. L’attribut DataType
donne la sémantique des données, plutôt que de décrire comment effectuer le rendu sur un écran, et il offre les avantages suivants dont vous ne bénéficiez pas avec DisplayFormat :
Le navigateur peut activer des fonctionnalités HTML5 (par exemple pour afficher un contrôle de calendrier, le symbole monétaire correspondant aux paramètres régionaux, des liens de messagerie, etc.).
Par défaut, le navigateur affiche les données à l’aide du format correspondant à vos paramètres régionaux.
L’attribut
DataType
peut permettre à MVC de choisir le modèle de champ correct pour afficher les données (DisplayFormat
, utilisé par lui-même, utilise le modèle de chaîne).
Notes
La validation jQuery ne fonctionne pas avec l’attribut Range
et DateTime
. Par exemple, le code suivant affiche toujours une erreur de validation côté client, même quand la date se trouve dans la plage spécifiée :
[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]
Vous devez désactiver la validation de date jQuery pour utiliser l’attribut Range
avec DateTime
. Il n’est généralement pas recommandé de compiler des dates dures dans vos modèles. Par conséquent, l’utilisation de l’attribut Range
et de DateTime
est déconseillée.
Le code suivant illustre la combinaison d’attributs sur une seule ligne :
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; }
}
Dans la partie suivante de la série, nous examinons l’application et nous apportons des améliorations aux méthodes Details
et Delete
générées automatiquement.
Ressources supplémentaires
Dans cette section :
- Une logique de validation est ajoutée au modèle
Movie
. - Vous vous assurez que les règles de validation sont appliquées chaque fois qu’un utilisateur crée ou modifie un film.
Ne vous répétez pas
L’un des principes de conception de MVC est « Ne vous répétez pas » (désigné par l’acronyme DRY, Don’t Repeat Yourself). ASP.NET Core MVC vous encourage à spécifier les fonctionnalités ou les comportements une seule fois, puis à utiliser la réflexion partout dans une application. Cela réduit la quantité de code à écrire, et rend le code que vous écrivez moins susceptible aux erreurs et plus facile à tester et à gérer.
La prise en charge de la validation fournie par MVC et Entity Framework Core Code First est un bon exemple du principe DRY en action. Vous pouvez spécifier de façon déclarative des règles de validation à un seul emplacement (dans la classe de modèle), et les règles sont appliquées partout dans l’application.
Ajouter des règles de validation au modèle de film
L’espace de noms DataAnnotations fournit un ensemble d’attributs de validation intégrés qui sont appliqués de façon déclarative à une classe ou à une propriété. DataAnnotations contient également des attributs de mise en forme, comme DataType
, qui aident à effectuer la mise en forme et ne fournissent aucune validation.
Mettez à jour la classe Movie
pour tirer parti des attributs de validation intégrés Required
, StringLength
, RegularExpression
et Range
.
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; }
}
}
Les attributs de validation spécifient le comportement que vous souhaitez appliquer sur les propriétés du modèle sur lesquels ils sont appliqués :
Les attributs
Required
etMinimumLength
indiquent qu’une propriété doit avoir une valeur, mais rien n’empêche un utilisateur d’entrer un espace pour satisfaire à cette validation.L’attribut
RegularExpression
sert à limiter les caractères pouvant être entrés. Dans le code précédent, « Genre » :- Doit utiliser seulement des lettres.
- La première lettre doit être une majuscule. Les espaces blancs sont autorisés tandis que les nombres et les caractères spéciaux ne sont pas autorisés.
L’expression
RegularExpression
« Rating » :- Nécessite que le premier caractère soit une lettre majuscule.
- Autorise les caractères spéciaux et les chiffres aux emplacements qui suivent. « PG-13 » est valide pour une évaluation, mais échoue pour un « Genre ».
L’attribut
Range
limite une valeur à une plage spécifiée.L’attribut
StringLength
vous permet de définir la longueur maximale d’une propriété de chaîne, et éventuellement sa longueur minimale.Les types valeur (tels que
decimal
,int
,float
etDateTime
) sont obligatoires par nature et n’ont pas besoin de l’attribut[Required]
.
L’application automatique des règles de validation par ASP.NET Core permet d’accroître la fiabilité de votre application. Cela garantit également que vous n’oublierez pas de valider un élément et que vous n’autoriserez pas par inadvertance l’insertion de données incorrectes dans la base de données.
Interface utilisateur des erreurs de validation
Exécutez l’application et accédez au contrôleur Movies.
Sélectionnez le lien Créer nouveau pour ajouter un nouveau film. Remplissez le formulaire avec des valeurs non valides. Dès que la validation côté client jQuery détecte l’erreur, elle affiche un message d’erreur.
Notes
Vous ne pourrez peut-être pas entrer de virgules décimales dans les champs décimaux. Pour prendre en charge la validation jQuery pour les paramètres régionaux autres que l’anglais qui utilisent une virgule (« , ») comme décimale et des formats de date autres que l’anglais des États-Unis, vous devez effectuer des étapes pour localiser votre application. Consultez ce commentaire GitHub 4076 pour savoir comment ajouter une virgule décimale.
Notez que le formulaire a affiché automatiquement un message d’erreur de validation approprié dans chaque champ contenant une valeur non valide. Les erreurs sont appliquées à la fois côté client (à l’aide de JavaScript et jQuery) et côté serveur (au cas où un utilisateur aurait désactivé JavaScript).
L’un des principaux avantages est que vous n’avez pas eu à changer une seule ligne de code dans la classe MoviesController
ou dans la vue Create.cshtml
pour activer cette interface utilisateur de validation. Le contrôleur et les vues créées précédemment dans ce didacticiel ont détecté les règles de validation que vous avez spécifiées à l’aide des attributs de validation sur les propriétés de la classe de modèle Movie
. Testez la validation à l’aide de la méthode d’action Edit
. La même validation est appliquée.
Les données de formulaire ne sont pas envoyées au serveur tant qu’il y a des erreurs de validation côté client. Vous pouvez vérifier cela en plaçant un point d’arrêt dans la méthode HTTP Post
, en utilisant l’outil Fiddler ou à l’aide des Outils de développement F12.
Fonctionnement de la validation
Vous vous demandez peut-être comment l’interface utilisateur de validation a été générée sans aucune mise à jour du code dans le contrôleur ou dans les vues. Le code suivant montre les deux méthodes 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);
}
La première méthode d’action (HTTP GET) Create
affiche le formulaire de création initial. La deuxième version ([HttpPost]
) gère la publication de formulaire. La seconde méthode Create
(la version [HttpPost]
) appelle ModelState.IsValid
pour vérifier si le film a des erreurs de validation. L’appel de cette méthode évalue tous les attributs de validation qui ont été appliqués à l’objet. Si l’objet comporte des erreurs de validation, la méthode Create
réaffiche le formulaire. S’il n’y a pas d’erreur, la méthode enregistre le nouveau film dans la base de données. Dans notre exemple de film, le formulaire n’est pas publié sur le serveur quand des erreurs de validation sont détectées côté client ; la seconde méthode Create
n’est jamais appelée quand il y a des erreurs de validation côté client. Si vous désactivez JavaScript dans votre navigateur, la validation client est désactivée et vous pouvez tester la méthode Create
HTTP POST ModelState.IsValid
pour détecter les erreurs de validation.
Vous pouvez définir un point d’arrêt dans la méthode [HttpPost] Create
et vérifier que la méthode n’est jamais appelée. La validation côté client n’enverra pas les données du formulaire quand des erreurs de validation seront détectées. Si vous désactivez JavaScript dans votre navigateur et que vous envoyez ensuite le formulaire avec des erreurs, le point d’arrêt sera atteint. Vous bénéficiez toujours d’une validation complète sans JavaScript.
L’illustration suivante montre comment désactiver JavaScript dans le navigateur Firefox.
L’illustration suivante montre comment désactiver JavaScript dans le navigateur Chrome.
Après la désactivation de JavaScript, publiez les données non valides et parcourez le débogueur.
Une partie du modèle d’affichage Create.cshtml
est indiquée dans le balisage suivant :
<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.*@
Le balisage précédent est utilisé par les méthodes d’action pour afficher le formulaire initial et pour le réafficher en cas d’erreur.
Le Tag Helper Input utilise les attributs DataAnnotations et produit les attributs HTML nécessaires à la validation jQuery côté client. Le Tag Helper Validation affiche les erreurs de validation. Pour plus d’informations, consultez Validation.
Le grand avantage de cette approche est que ni le contrôleur ni le modèle de vue Create
ne savent rien des règles de validation appliquées ou des messages d’erreur affichés. Les règles de validation et les chaînes d’erreur sont spécifiées uniquement dans la classe Movie
. Ces mêmes règles de validation sont automatiquement appliquées à la vue Edit
et à tous les autres modèles de vues que vous pouvez créer et qui modifient votre modèle.
Quand vous devez changer la logique de validation, vous pouvez le faire à un seul endroit en ajoutant des attributs de validation au modèle (dans cet exemple, la classe Movie
). Vous n’aurez pas à vous soucier des différentes parties de l’application qui pourraient être incohérentes avec la façon dont les règles sont appliquées. Toute la logique de validation sera définie à un seul emplacement et utilisée partout. Le code est ainsi très propre, facile à mettre à jour et évolutif. Et cela signifie que vous respecterez entièrement le principe DRY.
Utilisation d’attributs DataType
Ouvrez le fichier Movie.cs
et examinez la classe Movie
. L’espace de noms System.ComponentModel.DataAnnotations
fournit des attributs de mise en forme en plus de l’ensemble intégré d’attributs de validation. Nous avons déjà appliqué une valeur d’énumération DataType
aux champs de date de sortie et de prix. Le code suivant illustre les propriétés ReleaseDate
et Price
avec l’attribut DataType
approprié.
[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; }
Les attributs DataType
fournissent uniquement des indices permettant au moteur de vue de mettre en forme les données (et fournissent des éléments/attributs tels que <a>
pour les URL et <a href="mailto:EmailAddress.com">
pour l’e-mail). Vous pouvez utiliser l’attribut RegularExpression
pour valider le format des données. L’attribut DataType
sert à spécifier un type de données qui est plus spécifique que le type intrinsèque de la base de données ; il ne s’agit pas d’un attribut de validation. Dans le cas présent, nous voulons uniquement effectuer le suivi de la date, et non de l’heure. L’énumération DataType
fournit de nombreux types de données, telles que Date, Time, PhoneNumber, Currency ou EmailAddress. L’attribut DataType
peut également permettre à l’application de fournir automatiquement des fonctionnalités propres au type. Par exemple, vous pouvez créer un lien mailto:
pour DataType.EmailAddress
, et vous pouvez fournir un sélecteur de date pour DataType.Date
dans les navigateurs qui prennent en charge HTML5. Les attributs DataType
émettent des attributs HTML 5 data-
compréhensibles par les navigateurs HTML 5. Les attributs DataType
ne fournissent aucune validation.
DataType.Date
ne spécifie pas le format de la date qui s’affiche. Par défaut, le champ de données est affiché conformément aux formats par défaut basés sur le CultureInfo
du serveur.
L’attribut DisplayFormat
est utilisé pour spécifier explicitement le format de date :
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }
Le paramètre ApplyFormatInEditMode
indique que la mise en forme doit également être appliquée quand la valeur est affichée dans une zone de texte à des fins de modification. (Ceci peut ne pas être souhaitable pour certains champs ; par exemple, pour les valeurs monétaires, vous ne souhaiterez sans doute pas que le symbole monétaire figure dans la zone de texte.)
Vous pouvez utiliser l’attribut DisplayFormat
par lui-même, mais il est généralement préférable d’utiliser l’attribut DataType
. L’attribut DataType
donne la sémantique des données, plutôt que de décrire comment effectuer le rendu sur un écran, et il offre les avantages suivants dont vous ne bénéficiez pas avec DisplayFormat :
Le navigateur peut activer des fonctionnalités HTML5 (par exemple pour afficher un contrôle de calendrier, le symbole monétaire correspondant aux paramètres régionaux, des liens de messagerie, etc.).
Par défaut, le navigateur affiche les données à l’aide du format correspondant à vos paramètres régionaux.
L’attribut
DataType
peut permettre à MVC de choisir le modèle de champ correct pour afficher les données (DisplayFormat
, utilisé par lui-même, utilise le modèle de chaîne).
Notes
La validation jQuery ne fonctionne pas avec l’attribut Range
et DateTime
. Par exemple, le code suivant affiche toujours une erreur de validation côté client, même quand la date se trouve dans la plage spécifiée :
[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]
Vous devez désactiver la validation de date jQuery pour utiliser l’attribut Range
avec DateTime
. Il n’est généralement pas recommandé de compiler des dates dures dans vos modèles. Par conséquent, l’utilisation de l’attribut Range
et de DateTime
est déconseillée.
Le code suivant illustre la combinaison d’attributs sur une seule ligne :
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; }
}
}
Dans la partie suivante de la série, nous examinons l’application et nous apportons des améliorations aux méthodes Details
et Delete
générées automatiquement.
Ressources supplémentaires
Dans cette section :
- Une logique de validation est ajoutée au modèle
Movie
. - Vous vous assurez que les règles de validation sont appliquées chaque fois qu’un utilisateur crée ou modifie un film.
Ne vous répétez pas
L’un des principes de conception de MVC est « Ne vous répétez pas » (désigné par l’acronyme DRY, Don’t Repeat Yourself). ASP.NET Core MVC vous encourage à spécifier les fonctionnalités ou les comportements une seule fois, puis à utiliser la réflexion partout dans une application. Cela réduit la quantité de code à écrire, et rend le code que vous écrivez moins susceptible aux erreurs et plus facile à tester et à gérer.
La prise en charge de la validation fournie par MVC et Entity Framework Core Code First est un bon exemple du principe DRY en action. Vous pouvez spécifier de façon déclarative des règles de validation à un seul emplacement (dans la classe de modèle), et les règles sont appliquées partout dans l’application.
Ajouter des règles de validation au modèle de film
L’espace de noms DataAnnotations fournit un ensemble d’attributs de validation intégrés qui sont appliqués de façon déclarative à une classe ou à une propriété. DataAnnotations contient également des attributs de mise en forme, comme DataType
, qui aident à effectuer la mise en forme et ne fournissent aucune validation.
Mettez à jour la classe Movie
pour tirer parti des attributs de validation intégrés Required
, StringLength
, RegularExpression
et Range
.
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; }
}
Les attributs de validation spécifient le comportement que vous souhaitez appliquer sur les propriétés du modèle sur lesquels ils sont appliqués :
Les attributs
Required
etMinimumLength
indiquent qu’une propriété doit avoir une valeur, mais rien n’empêche un utilisateur d’entrer un espace pour satisfaire à cette validation.L’attribut
RegularExpression
sert à limiter les caractères pouvant être entrés. Dans le code précédent, « Genre » :- Doit utiliser seulement des lettres.
- La première lettre doit être une majuscule. Les espaces sont autorisés, tandis que les nombres et les caractères spéciaux ne le sont pas.
L’expression
RegularExpression
« Rating » :- Nécessite que le premier caractère soit une lettre majuscule.
- Autorise les caractères spéciaux et les chiffres aux emplacements qui suivent. « PG-13 » est valide pour une évaluation, mais échoue pour un « Genre ».
L’attribut
Range
limite une valeur à une plage spécifiée.L’attribut
StringLength
vous permet de définir la longueur maximale d’une propriété de chaîne, et éventuellement sa longueur minimale.Les types valeur (tels que
decimal
,int
,float
etDateTime
) sont obligatoires par nature et n’ont pas besoin de l’attribut[Required]
.
L’application automatique des règles de validation par ASP.NET Core permet d’accroître la fiabilité de votre application. Cela garantit également que vous n’oublierez pas de valider un élément et que vous n’autoriserez pas par inadvertance l’insertion de données incorrectes dans la base de données.
Interface utilisateur des erreurs de validation
Exécutez l’application et accédez au contrôleur Movies.
Appuyez sur le lien Create New pour ajouter un nouveau film. Remplissez le formulaire avec des valeurs non valides. Dès que la validation côté client jQuery détecte l’erreur, elle affiche un message d’erreur.
Notes
Vous ne pourrez peut-être pas entrer de virgules décimales dans les champs décimaux. Pour prendre en charge la validation jQuery pour les paramètres régionaux autres que l’anglais qui utilisent une virgule (« , ») comme décimale et des formats de date autres que l’anglais des États-Unis, vous devez effectuer des étapes pour localiser votre application. Consultez ce commentaire GitHub 4076 pour savoir comment ajouter une virgule décimale.
Notez que le formulaire a affiché automatiquement un message d’erreur de validation approprié dans chaque champ contenant une valeur non valide. Les erreurs sont appliquées à la fois côté client (à l’aide de JavaScript et jQuery) et côté serveur (au cas où un utilisateur aurait désactivé JavaScript).
L’un des principaux avantages est que vous n’avez pas eu à changer une seule ligne de code dans la classe MoviesController
ou dans la vue Create.cshtml
pour activer cette interface utilisateur de validation. Le contrôleur et les vues créées précédemment dans ce didacticiel ont détecté les règles de validation que vous avez spécifiées à l’aide des attributs de validation sur les propriétés de la classe de modèle Movie
. Testez la validation à l’aide de la méthode d’action Edit
. La même validation est appliquée.
Les données de formulaire ne sont pas envoyées au serveur tant qu’il y a des erreurs de validation côté client. Vous pouvez vérifier cela en plaçant un point d’arrêt dans la méthode HTTP Post
, en utilisant l’outil Fiddler ou à l’aide des Outils de développement F12.
Fonctionnement de la validation
Vous vous demandez peut-être comment l’interface utilisateur de validation a été générée sans aucune mise à jour du code dans le contrôleur ou dans les vues. Le code suivant montre les deux méthodes 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);
}
La première méthode d’action (HTTP GET) Create
affiche le formulaire de création initial. La deuxième version ([HttpPost]
) gère la publication de formulaire. La seconde méthode Create
(la version [HttpPost]
) appelle ModelState.IsValid
pour vérifier si le film a des erreurs de validation. L’appel de cette méthode évalue tous les attributs de validation qui ont été appliqués à l’objet. Si l’objet comporte des erreurs de validation, la méthode Create
réaffiche le formulaire. S’il n’y a pas d’erreur, la méthode enregistre le nouveau film dans la base de données. Dans notre exemple de film, le formulaire n’est pas publié sur le serveur quand des erreurs de validation sont détectées côté client ; la seconde méthode Create
n’est jamais appelée quand il y a des erreurs de validation côté client. Si vous désactivez JavaScript dans votre navigateur, la validation client est désactivée et vous pouvez tester la méthode Create
HTTP POST ModelState.IsValid
pour détecter les erreurs de validation.
Vous pouvez définir un point d’arrêt dans la méthode [HttpPost] Create
et vérifier que la méthode n’est jamais appelée. La validation côté client n’enverra pas les données du formulaire quand des erreurs de validation seront détectées. Si vous désactivez JavaScript dans votre navigateur et que vous envoyez ensuite le formulaire avec des erreurs, le point d’arrêt sera atteint. Vous bénéficiez toujours d’une validation complète sans JavaScript.
L’illustration suivante montre comment désactiver JavaScript dans le navigateur Firefox.
L’illustration suivante montre comment désactiver JavaScript dans le navigateur Chrome.
Après la désactivation de JavaScript, publiez les données non valides et parcourez le débogueur.
Une partie du modèle d’affichage Create.cshtml
est indiquée dans le balisage suivant :
<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.*@
Le balisage précédent est utilisé par les méthodes d’action pour afficher le formulaire initial et pour le réafficher en cas d’erreur.
Le Tag Helper Input utilise les attributs DataAnnotations et produit les attributs HTML nécessaires à la validation jQuery côté client. Le Tag Helper Validation affiche les erreurs de validation. Pour plus d’informations, consultez Validation.
Le grand avantage de cette approche est que ni le contrôleur ni le modèle de vue Create
ne savent rien des règles de validation appliquées ou des messages d’erreur affichés. Les règles de validation et les chaînes d’erreur sont spécifiées uniquement dans la classe Movie
. Ces mêmes règles de validation sont automatiquement appliquées à la vue Edit
et à tous les autres modèles de vues que vous pouvez créer et qui modifient votre modèle.
Quand vous devez changer la logique de validation, vous pouvez le faire à un seul endroit en ajoutant des attributs de validation au modèle (dans cet exemple, la classe Movie
). Vous n’aurez pas à vous soucier des différentes parties de l’application qui pourraient être incohérentes avec la façon dont les règles sont appliquées. Toute la logique de validation sera définie à un seul emplacement et utilisée partout. Le code est ainsi très propre, facile à mettre à jour et évolutif. Et cela signifie que vous respecterez entièrement le principe DRY.
Utilisation d’attributs DataType
Ouvrez le fichier Movie.cs
et examinez la classe Movie
. L’espace de noms System.ComponentModel.DataAnnotations
fournit des attributs de mise en forme en plus de l’ensemble intégré d’attributs de validation. Nous avons déjà appliqué une valeur d’énumération DataType
aux champs de date de sortie et de prix. Le code suivant illustre les propriétés ReleaseDate
et Price
avec l’attribut DataType
approprié.
[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
[Range(1, 100)]
[DataType(DataType.Currency)]
public decimal Price { get; set; }
Les attributs DataType
fournissent uniquement des indices permettant au moteur de vue de mettre en forme les données (et fournissent des éléments/attributs tels que <a>
pour les URL et <a href="mailto:EmailAddress.com">
pour l’e-mail). Vous pouvez utiliser l’attribut RegularExpression
pour valider le format des données. L’attribut DataType
sert à spécifier un type de données qui est plus spécifique que le type intrinsèque de la base de données ; il ne s’agit pas d’un attribut de validation. Dans le cas présent, nous voulons uniquement effectuer le suivi de la date, et non de l’heure. L’énumération DataType
fournit de nombreux types de données, telles que Date, Time, PhoneNumber, Currency ou EmailAddress. L’attribut DataType
peut également permettre à l’application de fournir automatiquement des fonctionnalités propres au type. Par exemple, vous pouvez créer un lien mailto:
pour DataType.EmailAddress
, et vous pouvez fournir un sélecteur de date pour DataType.Date
dans les navigateurs qui prennent en charge HTML5. Les attributs DataType
émettent des attributs HTML 5 data-
compréhensibles par les navigateurs HTML 5. Les attributs DataType
ne fournissent aucune validation.
DataType.Date
ne spécifie pas le format de la date qui s’affiche. Par défaut, le champ de données est affiché conformément aux formats par défaut basés sur le CultureInfo
du serveur.
L’attribut DisplayFormat
est utilisé pour spécifier explicitement le format de date :
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }
Le paramètre ApplyFormatInEditMode
indique que la mise en forme doit également être appliquée quand la valeur est affichée dans une zone de texte à des fins de modification. (Ceci peut ne pas être souhaitable pour certains champs ; par exemple, pour les valeurs monétaires, vous ne souhaiterez sans doute pas que le symbole monétaire figure dans la zone de texte.)
Vous pouvez utiliser l’attribut DisplayFormat
par lui-même, mais il est généralement préférable d’utiliser l’attribut DataType
. L’attribut DataType
donne la sémantique des données, plutôt que de décrire comment effectuer le rendu sur un écran, et il offre les avantages suivants dont vous ne bénéficiez pas avec DisplayFormat :
Le navigateur peut activer des fonctionnalités HTML5 (par exemple pour afficher un contrôle de calendrier, le symbole monétaire correspondant aux paramètres régionaux, des liens de messagerie, etc.).
Par défaut, le navigateur affiche les données à l’aide du format correspondant à vos paramètres régionaux.
L’attribut
DataType
peut permettre à MVC de choisir le modèle de champ correct pour afficher les données (DisplayFormat
, utilisé par lui-même, utilise le modèle de chaîne).
Notes
La validation jQuery ne fonctionne pas avec l’attribut Range
et DateTime
. Par exemple, le code suivant affiche toujours une erreur de validation côté client, même quand la date se trouve dans la plage spécifiée :
[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]
Vous devez désactiver la validation de date jQuery pour utiliser l’attribut Range
avec DateTime
. Il n’est généralement pas recommandé de compiler des dates dures dans vos modèles. Par conséquent, l’utilisation de l’attribut Range
et de DateTime
est déconseillée.
Le code suivant illustre la combinaison d’attributs sur une seule ligne :
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; }
}
Dans la partie suivante de la série, nous examinons l’application et nous apportons des améliorations aux méthodes Details
et Delete
générées automatiquement.