Aller au contenu principal

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 requise
  • DisplayName indique le nom du champ à utiliser dans le formulaire et les messages d'erreur
  • StringLength précise la longueur maximale d'un champ
  • Range précise la longueur minimale et maximale d'un champ

Annoter ConnexionViewModel

Snowfall.Web.Mvc/Models/Auth/ConnexionViewModel.cs
public class ConnexionViewModel
{
[Required]
[EmailAddress]
public string? Email { get; set; }

[Required]
[StringLength(16, MinimumLength = 8)]
[DataType(DataType.Password)]
public string? Password { get; set; }
}
info

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 que input 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.

Snowfall.Web.Mvc/Views/Auth/Connexion.cshtml
<!-- ... -->

<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.

Snowfall.Web.Mvc/Controllers/AuthController.cs
// 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);
}
info

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:

Snowfall.Web.Mvc/assets/scss/app.scss
//...

.input-validation-error {
@extend .is-invalid;
}

//...
info

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.

attention

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...

http://localhost:4200

party cat