Les formulaires
Notions théoriques
DataAnnotations pour la validation
Les DataAnnotations servent à la fois au mapping EF Core ET à la validation des formulaires. Quand un formulaire est soumis, ASP.NET Core valide automatiquement les données selon ces attributs :
using System.ComponentModel.DataAnnotations;
public class Article
{
[Required(ErrorMessage = "Le titre est obligatoire.")]
[StringLength(200, MinimumLength = 5,
ErrorMessage = "Le titre doit contenir entre 5 et 200 caractères.")]
[Display(Name = "Titre de l'article")]
public string Titre { get; set; } = string.Empty;
[Required(ErrorMessage = "Le contenu est obligatoire.")]
[MinLength(10, ErrorMessage = "Le contenu doit contenir au moins 10 caractères.")]
public string Contenu { get; set; } = string.Empty;
[EmailAddress(ErrorMessage = "L'adresse e-mail n'est pas valide.")]
public string? Email { get; set; }
[Range(0, 100, ErrorMessage = "La note doit être entre 0 et 100.")]
public int? Note { get; set; }
[Url(ErrorMessage = "L'URL n'est pas valide.")]
public string? SiteWeb { get; set; }
[RegularExpression(@"^\d{5}$", ErrorMessage = "Le code postal doit contenir 5 chiffres.")]
public string? CodePostal { get; set; }
}
Attributs de validation courants
| Attribut | Description |
|---|---|
[Required] | Champ obligatoire |
[StringLength(max, MinimumLength=min)] | Longueur entre min et max |
[MaxLength(n)] | Longueur maximale |
[MinLength(n)] | Longueur minimale |
[Range(min, max)] | Valeur numérique entre min et max |
[EmailAddress] | Format e-mail valide |
[Url] | Format URL valide |
[RegularExpression(pattern)] | Validation par expression régulière |
[Compare("AutreChamp")] | Deux champs doivent être identiques (ex: confirmation de mot de passe) |
ModelState.IsValid dans le contrôleur
Avant de sauvegarder, vérifiez ModelState.IsValid :
[HttpPost, ValidateAntiForgeryToken]
public async Task<IActionResult> Create(Article article)
{
if (ModelState.IsValid)
{
// Toutes les validations ont réussi → sauvegarder
_context.Add(article);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
// Au moins une validation a échoué → réafficher le formulaire avec les erreurs
return View(article);
}
Afficher les erreurs dans la vue Razor
Les Tag Helpers de validation affichent automatiquement les messages d'erreur :
<form asp-action="Create" method="post">
<!-- Résumé de toutes les erreurs (optionnel) -->
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="mb-3">
<!-- Label généré depuis [Display(Name = "...")] -->
<label asp-for="Titre" class="form-label"></label>
<!-- Input avec classe is-invalid si erreur -->
<input asp-for="Titre" class="form-control" />
<!-- Message d'erreur spécifique à ce champ -->
<span asp-validation-for="Titre" class="text-danger"></span>
</div>
<div class="mb-3">
<label asp-for="Contenu" class="form-label"></label>
<textarea asp-for="Contenu" class="form-control" rows="8"></textarea>
<span asp-validation-for="Contenu" class="text-danger"></span>
</div>
<button type="submit" class="btn btn-primary">Publier</button>
</form>
Validation côté client (jQuery Validate)
ASP.NET Core inclut la validation côté client automatique. Il faut inclure les scripts dans la section Scripts de la vue :
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
Cette validation s'exécute dans le navigateur avant l'envoi du formulaire — l'utilisateur voit les erreurs immédiatement, sans rechargement de page.
La validation côté client améliore l'expérience utilisateur, mais elle peut être contournée (JavaScript désactivé, requêtes HTTP directes). La validation côté serveur (ModelState.IsValid) doit toujours être présente. Elle est la seule garantie de sécurité.
// Symfony : contraintes sur l'entité (similaire)
use Symfony\Component\Validator\Constraints as Assert;
#[Assert\NotBlank(message: "Le titre est obligatoire")]
#[Assert\Length(max: 200)]
private string $titre = '';
// Spring Boot / Bean Validation (similaire)
@NotBlank(message = "Le titre est obligatoire")
@Size(max = 200)
private String titre;
Dans les trois frameworks, le principe est identique : les contraintes sont déclarées sur l'entité et vérifiées automatiquement lors de la soumission du formulaire.
Exemple pratique
Formulaire de création d'article complet avec validation :
// Models/Article.cs — Entité avec validations
public class Article
{
public int Id { get; set; }
[Required(ErrorMessage = "Le titre est obligatoire.")]
[StringLength(200, MinimumLength = 5,
ErrorMessage = "Le titre doit contenir entre 5 et 200 caractères.")]
[Display(Name = "Titre de l'article")]
public string Titre { get; set; } = string.Empty;
[Required(ErrorMessage = "Le contenu est obligatoire.")]
[MinLength(10, ErrorMessage = "Contenu trop court (minimum 10 caractères).")]
[Display(Name = "Contenu")]
public string Contenu { get; set; } = string.Empty;
public DateTime DateCreation { get; set; } = DateTime.UtcNow;
public bool EstPublie { get; set; }
}
<!-- Views/Articles/Create.cshtml -->
@model MonBlog.Models.Article
@{ ViewData["Title"] = "Nouvel article"; }
<h1>Créer un article</h1>
<form asp-action="Create" method="post" class="needs-validation">
<div asp-validation-summary="ModelOnly" class="alert alert-danger d-none"></div>
<div class="mb-3">
<label asp-for="Titre" class="form-label"></label>
<input asp-for="Titre" class="form-control" placeholder="Titre de votre article..." />
<span asp-validation-for="Titre" class="text-danger small"></span>
</div>
<div class="mb-3">
<label asp-for="Contenu" class="form-label"></label>
<textarea asp-for="Contenu" class="form-control" rows="12"
placeholder="Rédigez votre article ici..."></textarea>
<span asp-validation-for="Contenu" class="text-danger small"></span>
</div>
<div class="mb-3 form-check">
<input asp-for="EstPublie" class="form-check-input" type="checkbox" />
<label asp-for="EstPublie" class="form-check-label">Publier immédiatement</label>
</div>
<div class="d-flex gap-2">
<button type="submit" class="btn btn-primary">Publier</button>
<a asp-action="Index" class="btn btn-outline-secondary">Annuler</a>
</div>
</form>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
Test de mémorisation/compréhension
TP pour réfléchir et résoudre des problèmes
Vous allez améliorer la validation du formulaire de création d'articles de MonBlog.
Étape 1 — Ajouter des validations enrichies sur l'entité Article
Fournissez toujours un ErrorMessage clair dans vos attributs de validation. Le message par défaut généré par ASP.NET Core est en anglais et peu convivial. Un message en français, avec la contrainte explicite ("entre 5 et 200 caractères"), aide l'utilisateur à corriger son saisie du premier coup.
Étape 2 — Afficher les erreurs dans le formulaire Create
Ajoutez un <span asp-validation-for="..."> sous chaque champ de formulaire. Les utilisateurs voient ainsi immédiatement quel champ pose problème, sans avoir à chercher dans un résumé d'erreurs général.
Étape 3 — Activer la validation côté client
La validation côté client améliore l'expérience utilisateur en donnant un retour immédiat. Mais elle ne remplace pas ModelState.IsValid côté serveur. Implémentez toujours les deux : la validation client pour le confort, la validation serveur pour la sécurité.