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)%>
<% } %>

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

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")

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


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>

5
@Html.ValidationSummary(false,"", new { @class = "text-danger" })

Korzystanie z tej linii może być pomocne


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


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ą.


0

Możesz spróbować,

<div asp-validation-summary="All" class="text-danger"></div>

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”)}

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.