17-1 Validations et DataAnnotation
Vous avez peut-être remarqué qu'il est possible de soumettre le formulaire, que les champs soient remplis ou non.
Évidemment, pour un vrai formulaire, on cherchera à valider les champs.
Pour valider des champs, comme le formulaire est associé à un ViewModel (ConnexionViewModel), il est possible d'utiliser les validations de type DataAnnotation (https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/models-data/validation-with-the-data-annotation-validators-cs).
Les Data Annotations sont des attributs ajoutés aux modèles afin de les valider. Entre autres:
Requiredindique qu'une propriété est requiseDisplayNameindique le nom du champ à utiliser dans le formulaire et les messages d'erreurStringLengthprécise la longueur maximale d'un champRangeprécise la longueur minimale et maximale d'un champ
Annoter ConnexionViewModel
public class ConnexionViewModel
{
[Required]
[EmailAddress]
public string? Email { get; set; }
[Required]
[StringLength(16, MinimumLength = 8)]
[DataType(DataType.Password)]
public string? Password { get; set; }
}
Vous remarquerez que la dépendance suivante est ajoutée pour supporter les Data Annotations: using System.ComponentModel.DataAnnotations;.
[Required]: le champ est requis[EmailAddress]: le champ est un courriel et sera validé comme tel[StringLength(16, MinimumLength = 8)]: un champ de minimum 8 caractères et maximum 16.[DataType(DataType.Password)]: sera utilisé pour afficher le bon type de champ (password plutôt queinput text)
Ajouter les messages d'erreur au formulaire form (asp-validation-for)
Pour que les messages d'erreur soient affichés et associés aux champs du formulaire, on peut utiliser l'attribut asp-validation-for sur un span (ou autre élément pertinent). S'il y a des erreurs pour le champ en question, le message d'erreur sera ajoutée au span.
<!-- ... -->
<form asp-controller="Auth" asp-action="Authentifier">
<div class="form-floating mb-3">
<input asp-for="Email" placeholder="Courriel" class="form-control"/>
<label asp-for="Email">Courriel</label>
<span asp-validation-for="Email" class="invalid-feedback"></span>
</div>
<div class="form-floating mb-3">
<input type="password" asp-for="Password" placeholder="Mot de passe" class="form-control"/>
<label asp-for="Password">Mot de passe</label>
<span asp-validation-for="Password" class="invalid-feedback"></span>
</div>
<div class="form-group">
<button class="btn btn-primary">Connexion</button>
</div>
</form>
<!-- ... -->
Vérifier la validité du ViewModel dans le contrôleur
Lors de la soumission du formulaire (action Create), on doit vérifier que le modèle est valide avant, par exemple, de le sauvegarder dans la BD ou d'effectuer toute autre action.
- S'il est valide, on accepte les données
- S'il n'est pas valide, on retourne la vue
Newpour afficher les erreurs. Les erreurs seront automatiquement incluses avec le modèle.
Pour vérifier la validité du modèle associé à la vue, on peut utiliser ModelState.IsValid.
// POST /auth
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Authentifier(ConnexionViewModel connexionViewModel)
{
if (ModelState.IsValid)
{
var result = await _signInManager.PasswordSignInAsync(
connexionViewModel.Email,
connexionViewModel.Password,
true,
lockoutOnFailure: false
);
if (result.Succeeded)
return RedirectToAction("Index", "Evenements");
ModelState.AddModelError("Authentification.Echec", Resources.Controllers.AuthController.Authentification_Echec);
return View("Connexion", connexionViewModel);
}
return View("Connexion", connexionViewModel);
}
L'objet ModelState contient automatiquement l'état des validations du ViewModel. On peut vérifier son état à l'aide de ModelState.IsValid.
Si le ViewModel contient des erreurs, on retourne la vue à nouveau.
Test
Vous pouvez maintenant essayer de soumettre le formulaire...
Les validations ont l'air de fonctionner, mais pourquoi les messages d'erreur ne sont-ils pas affichés?
Ajout du support pour les validations Bootstrap
En fait, les validations sont bel et bien ajoutées au HTML, mais elles sont cachées.
<div class="form-floating mb-3">
<input placeholder="Courriel" class="form-control input-validation-error" type="email" data-val="true" data-val-email="The Email field is not a valid e-mail address." data-val-required="The Email field is required." id="Email" name="Email" value="">
<label for="Email">Courriel</label>
<span class="invalid-feedback field-validation-error" data-valmsg-for="Email" data-valmsg-replace="true">The Email field is required.</span>
</div>
La raison est que pour que bootstrap affiche le message d'erreur présent dans le span avec la classe css .invalid-feedback, il doit être adjacent à un champ (input par exemple) ayant la classe css .is-invalid.
Or, .NET Core MVC assigne la classe css .input-validation-error au input. Il est difficile de changer ce comportement, alors qu'il est facile de modifier Bootstrap puisqu'on utilise du Sass! :)
Ajoutez ceci à votre app.scss:
//...
.input-validation-error {
@extend .is-invalid;
}
//...
L'idée ici est qu'on dit que la classe CSS .input-validation-error "extend" .is-invalid de Bootstrap et aura donc le même comportement.
L'effet est que le span .invalid-feedback sera aussi affiché lorsqu'adjacent à un input avec la classe .input-validation-error.
Si vous n'utilisez pas le serveur d'assets de Vite, mais plutôt les assets précompilés, assurez-vous d'exécuter npm run build pour recompiler le CSS.
Maintenant, si on réessaie...

