ModelState.AddModelError - Jak dodać błąd, który nie dotyczy właściwości?

189

Sprawdzam moją bazę danych, Create(FooViewModel fvm){...}aby sprawdzić, czy fvm.prop1i fvm.prop2już istnieją w tej kombinacji; jeśli tak, chcę dodać błąd do stanu modelu, a następnie zwrócić cały widok. Próbowałem:

public ActionResult Create(FooViewModel fvm){
    if (ThatComboAlreadyExists(fvm)) {
      ModelState.AddModelError("Model", "There is already one like that");
      return View(fvm);
    }
}

... ale nie wyświetla się żaden błąd w Html.ValidationSummary, więc zakładam, że się pojawią. Podejrzewam, że „Model” nie jest właściwym kluczem, ale nie udało mi się znaleźć niczego po Google.

Scott Baker
źródło

Odpowiedzi:

330

W końcu natknąłem się na przykład użycia, którego szukałem - aby ogólnie przypisać błąd do Modelu, a nie jedną z jego właściwości, jak zwykle nazywacie:

ModelState.AddModelError(string key, string errorMessage);

ale użyj pustego ciągu dla klucza:

ModelState.AddModelError(string.Empty, "There is something wrong with Foo.");

Komunikat o błędzie pojawi się <%: Html.ValidationSummary() %>zgodnie z oczekiwaniami.

Scott Baker
źródło
22
Ten przypadek sprawia, że ​​myślę: dlaczego nie ma metody takiej jak ModelState.AddError(errorMessage)lub ModelState.AddGlobalError(errorMessage)... intuicyjne i łatwiej byłoby dowiedzieć się, jak dodać komunikat o błędzie niezwiązany z właściwościami żadnego modelu.
Rubens Mariuzzo
@Rubens: To prawda, ale możesz łatwo dodać taką metodę za pomocą metod rozszerzenia.
Johnny5,
2
Możesz również wyświetlić błąd, używając@Html.ValidationMessage(string.Empty)
Ben Foster
klucz jest właściwością twojego modelu powiązaną z widokiem - który ma błąd - tylko dla wyjaśnienia.
niico,
1
ValidationSummaryErrors(bool excludePropertyErrors)Przeciążenie wyświetli wszystkie błędy sprawdzania poprawności, gdy jego argument jest fałszywy lub tylko non-własność-specyficzne (key = „”) błędów, jeśli jego argumentem jest to prawda.
Suncat2000
26

Możesz dodać błąd modelu do dowolnej właściwości swojego modelu, sugeruję, jeśli nie ma nic związanego z tworzeniem nowej właściwości.

Jako przykład sprawdzamy, czy wiadomość e-mail jest już używana w DB, i dodajemy błąd do właściwości Email w akcji, więc kiedy zwracam widok, wiedzą, że wystąpił błąd i jak to pokazać, używając

<%: Html.ValidationSummary(true)%>
<%: Html.ValidationMessageFor(model => model.Email) %>

i

ModelState.AddModelError("Email", Resources.EmailInUse);
VinnyG
źródło
1
W moim przypadku wydaje się to sprzeczne z intuicją - sprawdzam, czy konkretna kombinacja col1 i col2 już istnieje w bazie danych, więc nie wydaje się właściwe posiadanie właściwości IsDuplicateOfAnotherRow w moim modelu ViewModel. Okazuje się, że możesz dodać błąd do swojego modelu - zobacz moją odpowiedź.
Scott Baker,
1
Czy istnieje sposób, aby uzyskać ciąg „E-mail” dla AddModelError bez użycia delikatnego ciągu literalnego? Jak (m=>m.email).SomeMagicToString()?
Snekse
Nie sądzę, musisz iść z magicznym sznurkiem ... nie najlepszym, ale wciąż dobrym rozwiązaniem
VinnyG
4
nameofOperator przyjście w C # 6.0 rozwiązuje ten magiczny ciąg problemów. msdn.microsoft.com/en-us/magazine/dn802602.aspx
RJ Cuthbertson
3

Umieszczenie właściwości kropki w ciągach znaków działało dla mnie: ModelState.AddModelError("Item1.Month", "This is not a valid date");

Chris
źródło
2
To rzeczywiście pokazuje nieprawidłowy miesiąc w interfejsie użytkownika, ale nie rozwiązuje pierwotnego problemu.
Scott Baker,
2
Pierwotny problem wynika z niezrozumienia, co „klucz” reprezentuje w metodzie. To rzuca nieco światła na funkcjonowanie „klucza”, więc dobrze jest wiedzieć, że klucz nie musi być tylko nazwą właściwości, ale może również odnosić się do właściwości zagnieżdżonych lub wartości specjalnej String.Empty.
Triynko,