À quoi ModelState.IsValid est-il valide dans ASP.NET MVC dans NerdDinner?

148

Sur l' exemple NerdDinner de Professional ASP.NET MVC 1.0, il existe une méthode pour créer un nouveau dîner copié ci-dessous (page 89 de la version gratuite de NerdDinner).

Là, il vérifie ModelState.IsValid pour true. Il semble vérifier si le modèle est valide pour la base de données (c'est-à-dire qu'il détecte les conversions de type de données, comme les dates au format invalide, mais pas les règles métier). Est-ce vrai?

Lors de la soumission du formulaire, si vous avez une erreur dans la date, ModelState.IsValid sera faux et vous obtiendrez une erreur, mais uniquement pour la date car AddRuleViolations n'a jamais été exécuté. Si vous supprimez complètement la vérification de ModelState.IsValid, vous obtiendrez toutes les erreurs (en raison de l'exception), y compris un marquage dans la date lorsqu'elle n'est pas valide. Alors, pourquoi la vérification de ModelState.IsValid y est-elle du tout? Est-ce que je manque quelque chose?

// 
// POST: /Dinners/Create 

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Create(Dinner dinner) {
    if (ModelState.IsValid) {
        try {
            dinner.HostedBy = "SomeUser"; 

            dinnerRepository.Add(dinner);
            dinnerRepository.Save();

            return RedirectToAction("Details", new {id = dinner.DinnerID }); 
        } catch {
            ModelState.AddRuleViolations(dinner.GetRuleViolations());
        } 
    } 
    return View(dinner); 
} 
pupeno
la source

Réponses:

143

ModelState.IsValidvous indique si des erreurs de modèle ont été ajoutées ModelState.

Le classeur de modèle par défaut ajoutera des erreurs pour les problèmes de conversion de type de base (par exemple, en passant un non-nombre pour quelque chose qui est un "int"). Vous pouvez remplir ModelState de manière plus complète en fonction du système de validation que vous utilisez.

Le DataAnnotationsclasseur d' exemple de modèle remplira l'état du modèle avec des erreurs de validation provenant des DataAnnotationsattributs de votre modèle.

Brad Wilson
la source
Brad existe-t-il un moyen de savoir si un modèle décoré avec DataAnnotations "IsValid" sans ModelState. (Disons par exemple que l'objet est chargé à partir d'un fichier ou utilisé dans une application console, etc.)
runxc1 Bret Ferrier
1
Non, ModelState.IsValid est le seul moyen de savoir s'il y a eu des erreurs de validation (ou de conversion de données) lors de la liaison de modèle.
Brad Wilson
@Brad, quand vous dites "Vous pouvez remplir ModelState de manière plus complète en fonction du système de validation que vous utilisez", comment cela est-il accompli? Existe-t-il un moyen d'ouvrir le code de validation ModelState pour mon ViewModel? J'utilise EF4, donc la plupart de ma validation est automatique prête à l'emploi.
WEFX
13
Utilisation: var errors = ModelState.Values.SelectMany(v => v.Errors);avec un point d'arrêt pour afficher les éventuels problèmes de validation.
full_prog_full
Parfois, c'est une erreur dans la table associée si les noms de propriété ont été modifiés, les migrations n'ont pas été effectuées et, par conséquent, SaveChanges (); échoue et ne peut pas se produire en raison du changement.
Oracular Man
25

De l'errata: ModelState.AddRuleViolations(dinner.GetRuleViolations());

Devrait être:

ModelState.AddModelErrors(dinner.GetRuleViolations());

Référence: http://www.wrox.com/WileyCDA/WroxTitle/Professional-ASP-NET-MVC-1-0.productCd-0470384611,descCd-ERRATA.html

Kelly Orr
la source
5
Depuis 2015, la AddModelErrorsméthode n'existe pas.
Felipe Correa
6
À partir de 2016, la ModelState.AddModelErrors()méthode existe
John
7
Depuis 2017, la ModelState.AddModelErrorméthode non plurielle existe.
Zachafer
0

Oui, Jared et Kelly Orr ont raison. J'utilise le code suivant comme dans l'exception d'édition.

foreach (var issue in dinner.GetRuleViolations())
{
    ModelState.AddModelError(issue.PropertyName, issue.ErrorMessage);
}

au lieu de

ModelState.AddRuleViolations(dinner.GetRuleViolations());
Phoe Htoo
la source
0

Tous les champs de modèle qui ont des types définis, ceux-ci doivent être validés lorsqu'ils sont renvoyés au Controller. Si l'un des champs de modèle ne correspond pas à leur type défini, ModelState.IsValid retournera false. Parce que, ces erreurs seront ajoutées dans ModelState.

B.Khan
la source