ModelState.IsValid == false, pourquoi?

120

Où puis-je trouver la liste des erreurs qui rendent ModelState invalide? Je n'ai vu aucune propriété d'erreurs sur l'objet ModelState.

Omu
la source

Réponses:

45

À propos de "peut-il être que 0 erreurs et IsValid == false": voici le code source MVC de https://github.com/Microsoft/referencesource/blob/master/System.Web/ModelBinding/ModelStateDictionary.cs#L37-L41

public bool IsValid {
    get {
        return Values.All(modelState => modelState.Errors.Count == 0);
    }
}

Maintenant, il semble que ce ne soit pas possible. Eh bien, c'est pour ASP.NET MVC v1.

reine3
la source
il me semble que ce ne devrait pas être le cas, est-ce que quelque chose ne va pas dans Values.All (modelState => modelState.Errors.Count == 0)?
Omu
Notez que l'erreur peut être un message ou une exception; par exemple Html.ValidationSummary n'affiche pas les exceptions (pour des raisons de sécurité je suppose); c'est peut-être pourquoi vous ne voyez pas d'erreurs? Comment vérifiez-vous l'absence d'erreurs?
queen3
1
ModelState.IsValid donne false
Omu
Ha-ha, c'est évident ... comment vérifier les "valeurs ont 0 erreur"?
queen3
258

Comme vous programmez probablement dans Visual Studio, vous feriez mieux de profiter de la possibilité d'utiliser des points d'arrêt pour des étapes de débogage aussi simples (avoir une idée du problème dans votre cas). Placez-les simplement devant / à l'endroit où vous vérifiez ModelState.isValid et survolez ModelState. Vous pouvez maintenant parcourir facilement toutes les valeurs à l'intérieur et voir quelle erreur provoque le retour isvalid false.

modèle

Bastijn
la source
3
est-il possible que toutes les valeurs aient 0 erreur et que l'état du modèle soit toujours invalide?
Omu
comme dit ci-dessus, non ce n'est pas possible :). Quelque part doit être un compte d'erreur! = 0.
bastijn
2
En complément, si le ErrorMessage est ambigu pour vous, vous pouvez accéder aux touches et il vous montrera à quelle variable il fait référence.
Lumineux le
1
dans votre vue, faites: @ Html.HiddenFor (model => model.Username) résoudra le problème!
Umit Kaya le
1
var asdf = ModelState.Values.Where(v => v.Errors.Count > 0);peut vous aider
Cirelli94
37

Collez le code ci-dessous dans le ActionResult de votre contrôleur et placez le débogueur à ce stade.

var errors = ModelState
    .Where(x => x.Value.Errors.Count > 0)
    .Select(x => new { x.Key, x.Value.Errors })
    .ToArray();
Krishna
la source
3
La meilleure réponse ici, devrait être mieux notée. Pourquoi passer mon temps à fouiller à travers 5 couches de l'objet ModelState dans le débogueur alors que je peux simplement en extraire les erreurs. Je serais là toute la matinée si je suivais la réponse la mieux notée
Sean T
2
c'est le meilleur de tous les temps
jouet le
23
bool hasErrors =  ViewData.ModelState.Values.Any(x => x.Errors.Count > 1);

ou itérer avec

    foreach (ModelState state in ViewData.ModelState.Values.Where(x => x.Errors.Count > 0))
    {

    }
Michael G
la source
est-il possible que toutes les valeurs aient 0 erreur et que l'état du modèle soit toujours invalide?
Omu
1
L'état du modèle aura une clé "Propriété" et une erreur associée dans le dictionnaire. le message d'erreur peut être vide, mais le nombre d'erreurs reflétera le nombre de propriétés non valides. Parce que la méthode ModelStateDictionary.AddModelError prend une clé et Exception ou erreur String; il est nécessaire d'ajouter une erreur de modèle.
Michael G
13

Parfois, un classeur lève une exception sans message d'erreur. Vous pouvez récupérer l'exception avec l'extrait de code suivant pour découvrir ce qui ne va pas:

(Souvent, si le classeur essaie de convertir des chaînes en types complexes, etc.)

 if (!ModelState.IsValid)
            {
var errors = ModelState.SelectMany(x => x.Value.Errors.Select(z => z.Exception));

// Breakpoint, Log or examine the list with Exceptions.

  }
Jonas Stensved
la source
1
Ce code m'a été très utile, mais l'itération des erreurs (exceptions) pour obtenir chaque .Message a abouti à une "référence d'objet non définie sur une instance d'un objet". Lorsque j'ai changé z.Exception en z.ErrorMessage, j'ai pu afficher les messages d'erreur.
StackOverflowUser
C'était la solution pour moi, en changeant en z.ErrorMessage, bien que je n'ai pas eu d'erreur avec z.Exception, juste des valeurs nulles. Cela vaut probablement la peine de mettre à jour la réponse originale.
esp
5

Si vous supprimez la vérification de ModelsState.IsValid et laissez l'erreur, si vous copiez cette ligne ((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrorset la collez dans la section de surveillance de Visual Studio, cela vous donnera exactement l'erreur. Gain de temps à vérifier où se trouve l'erreur.

Tom McDonough
la source
1
Astuce vraiment utile.
Ash
C'est le meilleur conseil de ce fil. Le problème que j'avais était un stupide "." (point) dans UserName
mangia
3

La propriété ModelState sur le contrôleur est en fait un objet ModelStateDictionary. Vous pouvez parcourir les clés du dictionnaire et utiliser la méthode IsValidField pour vérifier si ce champ particulier est valide.

Tvanfosson
la source
3

Comme je viens de m'arriver, cela peut également se produire lorsque vous ajoutez une propriété requise à votre modèle sans mettre à jour votre formulaire. Dans ce cas, le ValidationSummary ne listera pas le message d'erreur.

AndyP9
la source
1
Cela m'est arrivé. Thx pour la pointe!
Lewis86