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:
Required
indique qu'une propriété est requiseDisplayName
indique le nom du champ à utiliser dans le formulaire et les messages d'erreurStringLength
précise la longueur maximale d'un champRange
pré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
New
pour 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...
