Archive

Posts Tagged ‘ValidationSummary’

ASP.Net MVC : Eviter de polluer le modèle de la vue avec des messages d’erreurs

22 avril 2017 1 commentaire

J’ai récemment eu à répondre à une question posée sur le site StackOverflow. Je pose le contexte. Nous avons un modèle suivant:

public class ForgotPasswordMV
{
    [Display(Name = "Enter your email"), Required]
    public string Email { get; set; }
}

Ce modèle est utilisé dans l’action d’un contrôleur comme suit :

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Search(ForgotPasswordMV viewModel)
{
	if (Temp.Check(viewModel.Email))
		return RedirectToAction("VerifyToken", new { query = viewModel.Email });
	else
	{
		ViewBag.ErrorMessage = "Email not found or matched";
		return View();
	}
}

La question était de savoir si le fait d’utiliser la propriété dynamique ViewBag du contrôleur pour exposer le message d’erreur était une bonne pratique et que les recherches effectuées par le questionneur lui ont fait savoir qu’il fallait exposer une propriété au niveau du modèle.

Evidemment il est fortement recommandé de ne pas utiliser la propriété ViewBag étant donné qu’on ne bénéficie pas du typage fort. Si on veut communiquer avec la vue il faut toujours passer par un modèle typé. La solution proposée est donc légitime mais n’est pas une bonne pratique dans le cas de la gestion des erreurs du modèle dans le framework ASP.Net MVC.

La solution pour exposer les messages d’erreurs (comme dans l’exemple précédent qui n’utilise pas les attributs d’annotations de données) vient par l’utilisation de la méthode AddModelError de la classe ModelStateDictionary.  Nous n’avons pas besoin d’instancier cette classe étant donné qu’une propriété ModelState contenant une instance de cette classe existe déjà au niveau du contrôleur.

Du coup la bonne solution est de faire comme suit:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Search(ForgotPasswordMV viewModel)
{
    // ...
    else
    {
        this.ModelState.AddModelError("Email", "Email not found or matched");
        return View(viewModel);
    }
}

Il faut noter que cette méthode reçoit en premier paramètre le nom de la propriété du modèle à laquelle le message d’erreur est associé. Ainsi pour que pour ce message d’erreur soit affiché dans la vue à côté du champ Email il faut ajouter juste à côté de ce dernier la ligne suivante :

@Html.ValidationMessageFor(m => m.Email)

Cependant il est possible d’avoir un message d’erreur général à l’ensemble du modèle c’est à dire que ce message d’erreur n’est rattaché à aucune propriété du modèle. Pour cela il faudra utiliser une chaîne vide comme premier paramètre :

ModelState.AddModelError(String.Empty, "Email not found or matched");

Dans la vue Razor, il faudra utiliser la ligne suivante :

@Html.ValidationSummary(true, "The following error has occured:")

Le premier paramètre booléen indique qu’on ne veut pas afficher les messages d’erreur déjà rattachés à des propriétés du modèles.

Dans ce billet nous avons vu qu’on n’a pas besoin de polluer notre modèle et d’exposer des propriétés spécifiques aux messages d’erreur. Il suffit juste d’utiliser ce que nous offre le framework ASP.Net MVC pour nous faciliter la tâche.

J’espère que ce billet vous a été utile.

%d blogueurs aiment cette page :