To jest bardzo podobny problem do jednego już pisał tutaj: ASP.NET MVC: Validation messages set in TryUpdateModel not showning ValidationSummaryMVC ValidationSummary ignoruje błędy sprawdzania poprawności poziomie modelu po związaniu z użyciem TryUpdateModel
Nie jestem pewien, czy ten stary wątek był w nawiązaniu do wcześniejszej wersji MVC ale w MVC3 doświadczam dziwnych zachowań wzdłuż podobnych linii.
Mam klasy modelu o nazwie Trade. To dziedziczy po obiekcie IValidatableObject, dlatego implementuje metodę sprawdzania poprawności. W ramach tego mamy pewną walidację modelu jako całości (w przeciwieństwie do adnotacji danych wymuszających weryfikację właściwości). Walidacja jest następująca:
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var validationResults = new List<ValidationResult>();
if (this.EndDate < this.StartDate)
{
validationResults.Add(new ValidationResult("End date must be greater than start date"));
}
return validationResults;
}
Mamy model widoku, aby pomóc w wyświetlaniu transakcji. Zawiera odniesienie do modelu handlowego za pośrednictwem właściwości TradeModel. Zasadniczo model widoku jest modelem handlu, a także dodatkowymi informacjami dla populacji list rozwijanych, takich jak kontrahenci, itp.
Nasza klasa CSHTML zawiera ValidationSummary, z "prawdziwą" jako argumentem, co oznacza, że pokażą tylko błędy modelu.
Jeśli wdrożyć mój HttpPost metody kontrolera dla tworzenia nowego Handluj następująco ...
[HttpPost]
public ActionResult Create(FormCollection collection)
{
var trade = new Trade();
if (this.TryUpdateModel(trade))
{
if (this.SaveChanges(this.ModelState, trade))
{
return this.RedirectToAction("Index");
}
}
return this.View(trade);
}
... Kiedy wprowadzić handel z StartDate> DataZakończenia, jestem stwierdzenia, że TryUpdateModel zwraca false i użytkownik jest przekierowywany z powrotem do swojego handlu. Wydaje się to logiczne. Niestety ValidationSummary nie wyświetla żadnych komunikatów o błędach.
Jeśli umieściłem punkt przerwania w metodzie Create i zbadam modelStateState, widzę komunikat o błędzie w słowniku. Jest to sprzeczne z kluczem "TradeModel", a nie z żadną z właściwości. Ponownie wydaje się to logiczne.
Jedna z teorii wyjaśnia, dlaczego tak jest, jest taka, że ValidationSummary zakłada, że wszelkie błędy sprawdzania poprawności w odniesieniu do klucza, który nie jest łańcuchem String.Empty, muszą być błędami sprawdzania poprawności właściwości, ignoruje nasze błędy sprawdzania poprawności, ponieważ mamy model widoku zawierający odniesienie do modelu, w wyniku czego kluczem jest "TradeModel".
Co wieje tę teorię z wody jest taka: jeśli ja przepisać Tworzenie funkcji sterownika następująco ...
[HttpPost]
public ActionResult Create(Trade trade, FormCollection collection)
{
if (this.SaveChanges(this.ModelState, trade))
{
return this.RedirectToAction("Index");
}
return this.View(trade);
}
... a zatem polegać na MVC wykonywania wiązania „automatycznie”, a Ponownie uruchom ten sam scenariusz testowy, użytkownikowi zostanie wyświetlony komunikat o błędzie, który powinien zostać wyświetlony!
Jeśli dodaję punkt przerwania i zobaczę ModelState, widzę identyczne komunikaty o błędach z tymi samymi kluczami co poprzednio, ale tym razem ValidationSummary je podnosi!
Jeśli mogę zmienić walidacji następująco następnie współpracuje z Tworzenie funkcji sterownika napisany w obu kierunkach:
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var validationResults = new List<ValidationResult>();
if (this.EndDate < this.StartDate)
{
validationResults.Add(new ValidationResult("End date must be greater than start date", new[] { "StartDate" }));
}
return validationResults;
}
więc wyraźnie, że to tylko problem z błędami walidacji poziomie modelu.
Każda pomoc w tej sprawie byłaby bardzo ceniona! Istnieją powody (do których teraz nie wejdę), dlaczego musimy ręcznie utworzyć wystąpienie naszego modelu widoku i wywołać powiązanie za pomocą TryUpdateModel.
Z góry dziękuję!
UPDATE
Wydaje się, że teoria ValidationSummary wyświetlając tylko błędy z kluczem w ModelState z String.Empty kiedy powiedziano, aby wykluczyć błędy nieruchomość jest faktycznie prawdą. Sprawdziłem kod źródłowy i faktycznie używa ViewData.TemplateInfo.HtmlFieldPrefix, aby znaleźć błędy sprawdzania poprawności na poziomie modelu. Domyślnie jest to String.Empty.
Zmiana tej wartości na "TradeModel" wydaje się więc logiczna, ale powoduje, że każdy identyfikator lub nazwa HTML ma być prefiksem, więc powiązanie następnie kończy się niepowodzeniem!
Jeśli model widoku zawiera odniesienie do modelu biznesowego, wszystkie błędy dodane do ModelState przez obiekt IValidatableObject są dodawane z kluczem zawierającym przedrostek równy nazwie właściwości modelu biznesowego w modelu widoku (w naszym przypadku "TradeModel"), w wyniku czego klucze takie jak "TradeModel.CounterpartyId" itp. Błędy na poziomie modelu są dodawane z kluczem równym nazwie właściwości modelu biznesowego modelu widoku ("TradeModel").
Wygląda więc na to, że firma nie może dodać błędów sprawdzania poprawności na poziomie modelu, jeśli model widoku jest skonstruowany w ten sposób.
To, co mnie zastanawia, to dlaczego tak naprawdę działa w naszym "rzeczywistym" projekcie, kiedy funkcja tworzenia kontrolera jest napisana tak, że przyjmuje obiekt modelu widoku Trade jako argument. Pewnie przegapiłem to wczoraj, ale patrząc na to dzisiaj, kiedy MVC się wiąże i wywoływana jest walidacja, wydaje się, że dodaje dodatkowy klucz na końcu słownika o wartości String.Empty. Zawiera duplikat błędów dodanych za pomocą klucza TradeModel. Jak można się spodziewać, ValidationSummary następnie je podnosi!
Dlaczego więc MVC robi to w naszym projekcie na żywo, ale nie w prostej aplikacji testowej?
Widziałem sprawdzanie poprawności uruchamiane dwukrotnie, gdy funkcja kontrolera jest zapisana, aby wziąć model widoku jako argument. Może za każdym razem robi coś subtelnie innego?
UPDATE ... znowu
Powodem działa w naszym realnym projektem jest tam jakiś kod pochowany w naszej sterownika bazowego (z których wszystkie inne dziedziczą), które kopiuje wszystkie znalezione błędy w stanie do modelu nowy wpis z kluczem String.Empty. Ten kod był wywoływany tylko w jednym z dwóch scenariuszy. Tak więc nie ma rzeczywistej różnicy między aplikacjami rzeczywistymi i testowymi.
Teraz rozumiem, co się dzieje i dlaczego ValidationSummary zachowuje się w ten sposób.
Próbowałem ponownie zgłosić problem bez powodzenia. Dla mnie w nowym projekcie MVC3 twoja ** druga akcja ** 'public ActionResult Create (Trade trade, kolekcja FormCollection)' również ** nie wyświetla ** komunikatu potwierdzającego zgodnie z oczekiwaniami. Czy możesz stworzyć repro siebie w pustym projekcie, aby zweryfikować zachowanie, a może gdzieś przesłać? – nemesv
Interesujące. Dziękuję za próbę odtworzenia tego. Stworzę prosty przykład w nowym projekcie, jak sugerujesz. –
Stworzyłem prosty projekt i, jak powiedziałeś, nie działa on z żadną wersją funkcji tworzenia kontrolera. –