IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

MVC 3 et l'interface IValidatableObject

Date de publication : 07 avril 2011.

Par Jérôme HUGON (http://hugonjerome.developpez.com/) (Blog)
 

L'interface IValidatableObject, introduite avec la version 4 du framework .NET est prise en charge par MVC 3. Elle permet de réaliser une validation au niveau du modèle et vous permet de retourner des messages spécifiques sur l'état du modèle.

       Version PDF (Miroir)   Version hors-ligne (Miroir)
Viadeo Twitter Facebook Share on Google+        



Implémenter l'interface IValidatableObject
Intégrer la logique de validation dans le modèle
Le contrôleur
La vue
Personnaliser l'affichage des erreurs
Remerciements


Implémenter l'interface IValidatableObject

L'interface IValidatableObject est simple à implémenter, elle ne comporte qu'une méthode: Validate qui retourne un objet de type IEnumerable<ValidationResult>:
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace MvcSamples.Models
{
    public class TestModel : IValidatableObject
    {
        public string Title { get; set; }
        public string Description { get; set; }

        public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            // Do validation stuff here
        }
    }
}

Intégrer la logique de validation dans le modèle

Vous pouvez réaliser les tests correspondant à votre logique dans la méthode Validate et retourner un ou plusieurs messages d'erreur. Voici un exemple d'implémentation permettant de vérifier que chacune des propriétés contient une valeur :
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
    if (Title == null)
    {
        yield return new ValidationResult("The title is mandatory.");
    }
    if (Description == null)
    {
        yield return new ValidationResult("The description is mandatory.");
    }
}
Attention, la validation avec l'interface IValidatableObject n'est déclenchée que s'il n'y a pas d'erreur au niveau des propriétés. En effet, MVC 3 effectue dans un premier temps la validation des propriétés avant la validation des objets. En cas d'erreurs au niveau des propriétés, il n'y aura aucun déclenchement de la validation au niveau de l'objet avec l'interface IValidatableObject.


Le contrôleur

Dans le contrôleur, l'action qui reçoit la réponse du client peut effectuer un test sur la propriété IsValid de la propriété ModelState du contrôleur afin de déterminer si le modèle a passé toutes les étapes de validation ou non. A vous ensuite d'intégrer la logique de redirection :
[HttpPost]
public ActionResult Create(TestModel model)
{
    if (!ModelState.IsValid)
    {
        return View();
    }
    else
    {
        return View("Index");
    }
}
Vous remarquerez que pour afficher les erreurs dans la vue, il n'y a aucune méthode spécifique à appeller. La vue est retournée de manière classique.


La vue

Voici le code de la vue qui affiche le formulaire de création, rien de spécifique :
@model MvcSamples.Models.TestModel

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>TestModel</legend>

        @Html.EditorForModel()

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>
Voici le rendu au niveau du navigateur après avoir envoyé le formulaire sans données dans les champs :

MVC3 - IValidatableObject - 1

Personnaliser l'affichage des erreurs

Vous avez également la possibilité au moment de l'instanciation de l'objet ValidationResult de définir le/les champs concernés en spécifiant une collection de type string avec le nom des propriétés. Cela aura pour effet d'afficher les erreurs à côté des champs au lieu de l'afficher dans le résumé des erreurs de la page :
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
    if (Title == null || Description == null)
    {
        yield return new ValidationResult("All fields are mandatory.");
    }
    if (Title == null)
    {
        yield return new ValidationResult("*", new string[] { "Title" });
    }
    if (Description == null)
    {
        yield return new ValidationResult("*", new string[] { "Description" });
    }
}
Le rendu de la vue est automatiquement mis à jour sans avoir d'adaptations à effectuer dans celle-ci :

MVC3 - IValidatableObject - 2

Remerciements

Je remercie toute l'équipe developpez.com pour le temps passé à la publication de ce premier article et plus particulièrement Daniel Adam pour l'organisation, Youghourta Benali pour la technique et Claude Leloup pour la relecture.



               Version PDF (Miroir)   Version hors-ligne (Miroir)

Valid XHTML 1.0 TransitionalValid CSS!

Copyright © 2011 Jérôme HUGON. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.