ModelState.IsValid == false, dlaczego?

120

Gdzie mogę znaleźć listę błędów, które powodują, że parametr ModelState jest nieprawidłowy? Nie widziałem żadnej właściwości errors w obiekcie ModelState.

Omu
źródło

Odpowiedzi:

45

O „czy to możliwe, że 0 błędów i IsValid == false”: oto kod źródłowy MVC z 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);
    }
}

Teraz wygląda na to, że to niemożliwe. Cóż, to dla ASP.NET MVC v1.

królowa3
źródło
wydaje mi się, że nie powinno, czy to coś nie tak w Values.All (modelState => modelState.Errors.Count == 0)?
Omu
Zwróć uwagę, że błędem może być komunikat lub wyjątek; na przykład Html.ValidationSummary nie wyświetla wyjątków (chyba ze względów bezpieczeństwa); może dlatego nie widzisz błędów? Jak sprawdzić, czy nie ma błędów?
królowa 3
1
ModelState.IsValid daje false
Omu
Ha-ha, to oczywiste ... jak sprawdzić, czy „wartości mają 0 błędów”?
królowa 3
258

Ponieważ prawdopodobnie programujesz w Visual Studio, lepiej skorzystaj z możliwości użycia punktów przerwania dla tak łatwych kroków debugowania (aby dowiedzieć się, na czym polega problem w Twoim przypadku). Po prostu umieść je tuż przed / w miejscu, w którym sprawdzasz ModelState.isValid i najedź kursorem na ModelState. Teraz możesz łatwo przejrzeć wszystkie wartości wewnątrz i zobaczyć, jaki błąd powoduje, że isvalid zwraca false.

modelstate

bastijn
źródło
3
czy to możliwe, że wszystkie wartości mają 0 błędów, a stan modelu nadal jest nieprawidłowy?
Omu
jak wspomniano powyżej, nie jest to możliwe :). Gdzieś musi być liczba błędów! = 0.
bastijn
2
Jako dodatek, jeśli komunikat o błędzie jest dla Ciebie niejednoznaczny, możesz przejść do kluczy i pokaże ci, do której zmiennej się odnosi.
Luminous
1
w swoim widoku zrób: @ Html.HiddenFor (model => model.Username) rozwiąże problem!
Umit Kaya
1
var asdf = ModelState.Values.Where(v => v.Errors.Count > 0);może ci pomóc
Cirelli94
37

Wklej poniższy kod w ActionResult kontrolera i umieść debuger w tym miejscu.

var errors = ModelState
    .Where(x => x.Value.Errors.Count > 0)
    .Select(x => new { x.Key, x.Value.Errors })
    .ToArray();
Kryszna
źródło
3
Najlepsza odpowiedź tutaj, powinna zostać oceniona wyżej. Po co tracić czas na przekopywanie się przez 5 warstw obiektu ModelState w debugerze, skoro mogę po prostu wyciągnąć z niego błędy. Byłbym tam cały ranek, gdybym podążał za odpowiedzią, która została najwyżej oceniona
Sean T
2
to jest najlepsze w historii
zabawka
23
bool hasErrors =  ViewData.ModelState.Values.Any(x => x.Errors.Count > 1);

lub iteruj z

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

    }
Michael G.
źródło
czy to możliwe, że wszystkie wartości mają 0 błędów, a stan modelu nadal jest nieprawidłowy?
Omu
1
Stan modelu będzie miał klucz „Właściwość” i powiązany błąd w słowniku. komunikat o błędzie może być pusty, ale liczba błędów będzie odzwierciedlać liczbę nieprawidłowych właściwości. Ponieważ metoda ModelStateDictionary.AddModelError przyjmuje klucz, a wyjątek lub ciąg błędu; wymagane jest dodanie błędu modelu.
Michael G
13

Czasami spinacz zgłasza wyjątek bez komunikatu o błędzie. Możesz pobrać wyjątek za pomocą następującego fragmentu kodu, aby dowiedzieć się, co jest nie tak:

(Często, jeśli spinacz próbuje przekonwertować ciągi na złożone typy itp.)

 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
źródło
1
Ten kod był dla mnie bardzo pomocny, ale iteracja błędów (wyjątków) w celu pobrania każdego .Message spowodowała, że ​​„odwołanie do obiektu nie zostało ustawione na instancję obiektu”. Kiedy zmieniłem z.Exception na z.ErrorMessage, mogłem wyświetlać komunikaty o błędach.
StackOverflowUser
To było dla mnie rozwiązanie, przechodząc na z.ErrorMessage, chociaż nie otrzymałem błędu z z.Exception, tylko wartości null. Chyba warto zaktualizować oryginalną odpowiedź.
szczególnie
5

Jeśli usuniesz sprawdzanie dla ModelsState.IsValid i pozwolisz na błąd, jeśli skopiujesz ten wiersz ((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrorsi wkleisz go w sekcji obserwacyjnej w programie Visual Studio, otrzymasz dokładnie, jaki jest błąd. Oszczędza dużo czasu, sprawdzając, gdzie jest błąd.

Tom McDonough
źródło
1
Naprawdę pomocna wskazówka.
Ash
To najlepsza rada w tym wątku. Problem, który miałem, był głupi ”. (kropka) w UserName
mangia
3

Właściwość ModelState kontrolera jest w rzeczywistości obiektem ModelStateDictionary. Możesz iterować za pomocą kluczy w słowniku i użyć metody IsValidField, aby sprawdzić, czy to konkretne pole jest prawidłowe.

tvanfosson
źródło
3

Tak jak mi się właśnie przydarzyło - może się to również zdarzyć, gdy dodasz wymaganą właściwość do swojego modelu bez aktualizacji formularza. W takim przypadku podsumowanie walidacji nie wyświetli komunikatu o błędzie.

AndyP9
źródło
1
To mi się przydarzyło. Dzięki za wskazówkę!
Lewis86