NerdDinner'da ASP.NET MVC'de ModelState.IsValid ne için geçerlidir?


148

Açık NerdDinner örneğinde Profesyonel ASP.NET MVC 1.0 kopyalanan körük (serbest NerdDinner versiyonunun sayfa 89) gibi yeni bir akşam yemeği oluşturmak için bir yöntem var.

Orada ModelState.IsValid'i doğru olarak kontrol eder. Modelin veritabanı için geçerli olup olmadığını kontrol ediyor gibi görünüyor (yani, geçersiz biçime sahip tarihler gibi, ancak iş kurallarına sahip olmayan tarihler gibi veri türü dönüşümlerini yakalıyor). Bu doğru mu?

Formu gönderirken, tarihte bir hata varsa, ModelState.IsValid yanlış olur ve bir hata alırsınız, ancak yalnızca tarih için AddRuleViolations hiçbir zaman yürütülemedi. ModelState.IsValid kontrolünü tamamen kaldırırsanız, geçersiz olduğu tarihteki bir işaret de dahil olmak üzere tüm hataları (istisna nedeniyle) alırsınız. Öyleyse, ModelState.IsValid kontrolü neden orada? Bir şey mi kaçırıyorum?

// 
// 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); 
} 

Yanıtlar:


145

ModelState.IsValid'a herhangi bir model hatası eklenip eklenmediğini gösterir ModelState.

Varsayılan model bağlayıcı, temel tür dönüştürme sorunları için bazı hatalar ekler (örneğin, "int" olan bir şey için sayı olmayan bir sayıyı iletmek). ModelState'i, kullandığınız doğrulama sistemine göre daha eksiksiz doldurabilirsiniz.

Örnek DataAnnotationsmodel bağlayıcı, model durumunu DataAnnotations, modelinizdeki özniteliklerden alınan doğrulama hatalarıyla doldurur .


Brad, ModelState olmadan DataAnnotations "IsValid" ile dekore edilmiş bir Model olup olmadığını öğrenmenin herhangi bir yolu var. (Örneğin, Nesnenin bir dosyadan yüklendiğini veya bir Konsol Uygulamasında kullanıldığını
varsayalım

1
Hayır, ModelState.IsValid, model bağlama sırasında herhangi bir doğrulama (veya veri dönüştürme) hatası olup olmadığını bilmenin tek yoludur.
Brad Wilson

@Brad, "ModelState'i, kullandığınız doğrulama sistemine göre daha eksiksiz doldurabilirsiniz" dediğinizde, bu nasıl başarılır? ViewModel'im için ModelState doğrulama kodumu kırmanın bir yolu var mı? EF4 kullanıyorum, bu nedenle doğrulama işlemimin çoğu otomatik olarak kutudan çıkarılır.
WEFX

13
Kullanım: var errors = ModelState.Values.SelectMany(v => v.Errors);herhangi bir doğrulama sorununu görüntülemek için bir kesme noktasıyla.
full_prog_full

Özellik adları değiştirilmişse, geçişler yapılmamışsa ve sonuç olarak SaveChanges (); başarısız olur ve değişiklik nedeniyle oluşamaz.
Oracular Man

25

Hatalardan: ModelState.AddRuleViolations(dinner.GetRuleViolations());

Olmalı:

ModelState.AddModelErrors(dinner.GetRuleViolations());

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


5
2015 itibariyle bu AddModelErrorsyöntem mevcut değil.
Felipe Correa

6
2016 itibariyle, ModelState.AddModelErrors()yöntem mevcuttur
John

8
2017 itibariyle çoğul olmayan ModelState.AddModelErroryöntem mevcuttur.
Zachafer

1

Belirli türleri olan tüm model alanları, Denetleyiciye iade edildiğinde doğrulanmalıdır. Model alanlarından herhangi biri tanımlanmış türleriyle eşleşmiyorsa, ModelState.IsValid false döndürür. Çünkü bu hatalar ModelState'e eklenecektir.


0

Evet, Jared ve Kelly Orr haklı. Aşağıdaki kodu düzenleme istisnasında olduğu gibi kullanıyorum.

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

onun yerine

ModelState.AddRuleViolations(dinner.GetRuleViolations());
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.