ASP.NET MVC Html.ValidationSummary (true) nie wyświetla błędów modelu

194

Mam problem z Html.ValidationSummary. Nie chcę wyświetlać błędów właściwości w ValidationSummary. A kiedy ustawię Html.ValidationSummary (true), nie wyświetla komunikatów o błędach z ModelState. Gdy występuje wyjątek w działaniu kontrolera na łańcuch

MembersManager.RegisterMember(member);

sekcja catch dodaje błąd do ModelState:

ModelState.AddModelError("error", ex.Message);

Ale ValidationSummary nie wyświetla tego komunikatu o błędzie. Po ustawieniu Html.ValidationSummary (false) wszystkie komunikaty są wyświetlane, ale nie chcę wyświetlać błędów właściwości. Jak mogę rozwiązać ten problem?

Oto kod, którego używam:

Model:

public class Member
{
        [Required(ErrorMessage = "*")]
        [DisplayName("Login:")]
        public string Login { get; set; }

        [Required(ErrorMessage = "*")]
        [DataType(DataType.Password)]
        [DisplayName("Password:")]
        public string Password { get; set; }

        [Required(ErrorMessage = "*")]
        [DataType(DataType.Password)]
        [DisplayName("Confirm Password:")]
        public string ConfirmPassword { get; set; }
}

Kontroler:

[HttpPost]
public ActionResult Register(Member member)
{
    try
    {
        if (!ModelState.IsValid)
            return View();

        MembersManager.RegisterMember(member);
    }
    catch (Exception ex)
    {
        ModelState.AddModelError("error", ex.Message);

        return View(member);
    }
}

Widok:

<% using (Html.BeginForm("Register", "Members", FormMethod.Post, 
                        new { enctype = "multipart/form-data" })) {%> 
    <p>
        <%= Html.LabelFor(model => model.Login)%>
        <%= Html.TextBoxFor(model => model.Login)%>
        <%= Html.ValidationMessageFor(model => model.Login)%>
    </p>

    <p>
        <%= Html.LabelFor(model => model.Password)%>
        <%= Html.PasswordFor(model => model.Password)%>
        <%= Html.ValidationMessageFor(model => model.Password)%>
    </p>

    <p>
        <%= Html.LabelFor(model => model.ConfirmPassword)%>
        <%= Html.PasswordFor(model => model.ConfirmPassword)%>
        <%= Html.ValidationMessageFor(model => model.ConfirmPassword)%>
    </p>

    <div>
        <input type="submit" value="Create" />
    </div>

    <%= Html.ValidationSummary(true)%>
<% } %>
msi
źródło

Odpowiedzi:

324

Uważam, że sposób działania flagi ValidationSummary polega na tym, że wyświetla tylko ModelErrors string.emptyjako klucz. W przeciwnym razie przyjmuje się, że jest to błąd właściwości. Dodawany błąd niestandardowy ma klucz „błąd”, więc nie będzie wyświetlany po wywołaniu ValidationSummary (true). Musisz dodać niestandardowy komunikat o błędzie z pustym kluczem, takim jak ten:

ModelState.AddModelError(string.Empty, ex.Message);
Ukłucie
źródło
9
@LordCover: Zgaduję, że to „działa zgodnie z przeznaczeniem”, a nie błąd - przeciążenie ValidationSummary () używane domyślnie wyklucza błędy ModelState związane z właściwościami samego modelu. To pozostawia te błędy do reprezentowania przez Html.ValidationMessageFor () wywołuje każdą indywidualną właściwość bez konieczności ich duplikowania w podsumowaniu. Pamiętając o tym, wygląda na to, że każdy błąd modelu dodany z niepustym kluczem zakłada się, że jest powiązany z właściwością modelu, nawet jeśli klucz nie pasuje do nazwy właściwości.
Daniel Schaffer
26
Uwaga dla innych implementatorów: ModelState.AddModelError(string.Empty, ex);też nie działa. Musisz użyć ModelState.AddModelError(string, string)przeciążenia, jak pokazano powyżej.
wolfyuk
2
aktualizacja: w MVC4 już tak nie jest. ModelState.AddModelError („”, ex.Message); działa
Neil Thompson
4
MVC5 Wciąż musiałem zadzwonić do ex.Message, aby go uruchomić.
smiggleworth
uratował dzień! MVC5 wciąż ma pewne problemy :)
juFo
67

Działa to lepiej, ponieważ można wyświetlić komunikat sprawdzania poprawności dla określonego klucza:

    ModelState.AddModelError("keyName","Message");

i wyświetl to w następujący sposób:

    @Html.ValidationMessage("keyName")
ingvesund
źródło
28

Wiem, że jest to trochę stare i zostało oznaczone jako odpowiedzi przy 147 głosach, ale jest jeszcze coś do rozważenia.

Możesz mieć wszystkie błędy modelu, właściwość o nazwie i string. Puste klucze, w razie potrzeby pokazywane w ValidationSummary. W ValidationSummary występuje przeciążenie, które to zrobi.

    //   excludePropertyErrors:
    //   true to have the summary display model-level errors only, or false to have
    //   the summary display all errors.
    public static MvcHtmlString ValidationSummary(this HtmlHelper htmlHelper, bool excludePropertyErrors);

wprowadź opis zdjęcia tutaj

Levitikon
źródło
5
Tak! Wystarczy zmienić @Html.ValidationSummary(true, "", new { @class = "text-danger" })na@Html.ValidationSummary(false, "", new { @class = "text-danger" })
Xeningem,
7

Może tak:

[HttpPost]
public ActionResult Register(Member member)
{
    try
    {
       if (!ModelState.IsValid)
       {
          ModelState.AddModelError("keyName", "Form is not valid");
          return View();
       }
       MembersManager.RegisterMember(member);
    }
    catch (Exception ex)
    {
       ModelState.AddModelError("keyName", ex.Message);
       return View(member);
    }
}

I na wyświetlaczu dodaj:

<div class="alert alert-danger">
  @Html.ValidationMessage("keyName")
</div>

LUB

<div class="alert alert-danger">
  @Html.ValidationSummary(false)
</div>
Piotr Knut
źródło
5
@Html.ValidationSummary(false,"", new { @class = "text-danger" })

Korzystanie z tej linii może być pomocne

sachind
źródło
Dodaj powyższą linię w pliku cshtml.
sachind
2

W moim przypadku nie działało z powodu powrotu.

Zamiast używać:

return RedirectToAction("Rescue", "CarteiraEtapaInvestimento", new { id = investimento.Id, idCarteiraEtapaResgate = etapaDoResgate.Id });

Użyłem:

return View("ViewRescueCarteiraEtapaInvestimento", new CarteiraEtapaInvestimentoRescueViewModel { Investimento = investimento, ValorResgate = investimentoViewModel.ValorResgate });

To model, więc obvius ModelState.AddModelError("keyName","Message");musi współpracować z modelem.

Ta odpowiedź pokazuje, dlaczego. Dodawanie sprawdzania poprawności za pomocą DataAnnotations

Allan Patrick Patzlaff
źródło
0

Jeśli prawie wszystko wydaje się słuszne, inną rzeczą, na którą należy zwrócić uwagę, jest upewnienie się, że podsumowanie walidacji nie jest jawnie ukryte za pomocą jakiegoś zastąpienia CSS, takiego jak to:

.validation-summary-valid {
    display: none;
}

Może to również powodować @Html.ValidationSummaryukrywanie się, ponieważ podsumowanie jest dynamicznie renderowane z validation-summary-validklasą.

alex
źródło
0

Możesz spróbować,

<div asp-validation-summary="All" class="text-danger"></div>
Adrita Sharma
źródło
Uwaga - musi to być <div>, jeśli jest to <span>, nie będzie renderowany.
Stephen Angell
-4

DODAJ go w najniższej części swojego widoku:

@section Scripts {@ Scripts.Render („~ / bundles / jqueryval”)}

ronIT
źródło