Co to jest ModelState.IsValid ważne w ASP.NET MVC w NerdDinner?

148

W przykładzie programu NerdDinner Professional ASP.NET MVC 1.0 istnieje metoda tworzenia nowej kolacji zgodnie z poniższym opisem (strona 89 bezpłatnej wersji NerdDinner).

Tam sprawdza wartość ModelState.IsValid. Wydaje się, że sprawdza, czy model jest prawidłowy dla bazy danych (to znaczy wychwytuje konwersje typów danych, takie jak daty z nieprawidłowym formatem, ale nie reguł biznesowych). Czy to prawda?

Podczas przesyłania formularza, jeśli masz błąd w dacie, ModelState.IsValid będzie fałszywe i otrzymasz błąd, ale tylko dla daty, ponieważ AddRuleViolations nigdy nie zostało wykonane. Jeśli całkowicie usuniesz czek dla ModelState.IsValid, otrzymasz wszystkie błędy (z powodu wyjątku), w tym oznaczenie daty, kiedy jest nieważne. Dlaczego więc w ogóle tam jest sprawdzenie ModelState.IsValid? Czy coś mi brakuje?

// 
// 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
źródło

Odpowiedzi:

143

ModelState.IsValidinformuje, czy zostały dodane jakiekolwiek błędy modelu ModelState.

Domyślny spinacz modelu doda kilka błędów dla podstawowych problemów z konwersją typów (na przykład przekazanie wartości innej niż liczba dla czegoś, co jest „int”). Możesz pełniej wypełnić ModelState w oparciu o dowolny używany system walidacji.

Przykładowy DataAnnotationsspinacz modelu wypełni stan modelu błędami walidacji pobranymi z DataAnnotationsatrybutów modelu.

Brad Wilson
źródło
Brad jest w jakikolwiek sposób, aby dowiedzieć się, czy model ozdobiony adnotacjami DataAnnotations „IsValid” bez ModelState. (Załóżmy na przykład, że obiekt jest ładowany z pliku lub używany w aplikacji konsolowej itp.)
runxc1 Bret Ferrier
1
Nie, ModelState.IsValid to jedyny sposób, aby dowiedzieć się, czy podczas wiązania modelu wystąpiły jakiekolwiek błędy walidacji (lub konwersji danych).
Brad Wilson
@Brad, kiedy mówisz "Możesz wypełnić ModelState bardziej w oparciu o dowolny używany system walidacji", jak to się robi? Czy istnieje sposób na złamanie mojego kodu walidacji ModelState dla mojego ViewModel? Używam EF4, więc większość mojej weryfikacji odbywa się automatycznie po wyjęciu z pudełka.
WEFX
13
Zastosowanie: var errors = ModelState.Values.SelectMany(v => v.Errors);z punktem przerwania, aby wyświetlić wszelkie problemy z walidacją.
full_prog_full
Czasami jest to błąd w powiązanej tabeli, jeśli nazwy właściwości zostały zmienione, migracje nie zostały przeprowadzone iw rezultacie SaveChanges (); kończy się niepowodzeniem i nie może wystąpić z powodu zmiany.
Oracular Man
25

Z Errata: ModelState.AddRuleViolations(dinner.GetRuleViolations());

Powinien być:

ModelState.AddModelErrors(dinner.GetRuleViolations());

Źródła: http://www.wrox.com/WileyCDA/WroxTitle/Professional-ASP-NET-MVC-1-0.productCd-0470384611,descCd-ERRATA.html

Kelly Orr
źródło
5
Od 2015 r. AddModelErrorsMetoda nie istnieje.
Felipe Correa
6
Od 2016 r. ModelState.AddModelErrors()Metoda istnieje
Jan
7
Od 2017 r ModelState.AddModelError. Istnieje metoda nieliczbowa.
Zachafer
0

Tak, Jared i Kelly Orr mają rację. Używam następującego kodu jak w wyjątku edycji.

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

zamiast

ModelState.AddRuleViolations(dinner.GetRuleViolations());
Phoe Htoo
źródło
0

Wszystkie pola modelu, które mają określone typy, powinny zostać zweryfikowane po zwróceniu do kontrolera. Jeśli którekolwiek z pól modelu nie jest zgodne ze zdefiniowanym typem, wówczas ModelState.IsValid zwróci wartość false. Ponieważ te błędy zostaną dodane w ModelState.

B.Khan
źródło