ASP.NET MVC Html.ValidationSummary (true) не отображает ошибки модели

194

У меня есть некоторые проблемы с Html.ValidationSummary. Я не хочу отображать ошибки свойств в ValidationSummary. И когда я устанавливаю Html.ValidationSummary (true), он не отображает сообщения об ошибках из ModelState. Когда есть некоторое исключение в действии контроллера на строку

MembersManager.RegisterMember(member);

Секция catch добавляет ошибку в ModelState:

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

Но ValidationSummary не отображает это сообщение об ошибке. Когда я устанавливаю Html.ValidationSummary (false), отображаются все сообщения, но я не хочу отображать ошибки свойств. Как я могу решить эту проблему?

Вот код, который я использую:

Модель:

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

контроллер:

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

Посмотреть:

<% 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
источник

Ответы:

324

Я полагаю, что флаг ValidationSummary работает так, что он отображает только ModelErrors в string.emptyкачестве ключа. В противном случае предполагается, что это ошибка свойства. Пользовательская ошибка, которую вы добавляете, имеет ключ 'error', поэтому она не будет отображаться при вызове ValidationSummary (true). Вам необходимо добавить свое собственное сообщение об ошибке с пустым ключом, например так:

ModelState.AddModelError(string.Empty, ex.Message);
прививка
источник
9
@LordCover: Я предполагаю, что это «работает как задумано», а не ошибка - перегрузка ValidationSummary (), используемая по умолчанию, исключает ошибки ModelState, связанные со свойствами самой модели. В результате эти ошибки будут представлены вызовами Html.ValidationMessageFor () для каждого отдельного свойства без дублирования их в сводке. При этом представляется, что любая ошибка модели, добавленная с непустым ключом, предполагается связанной со свойством модели, даже если ключ не соответствует имени свойства.
Даниэль Шаффер
26
Просто примечание для других разработчиков: ModelState.AddModelError(string.Empty, ex);похоже, тоже не работает. Вы должны использовать ModelState.AddModelError(string, string)перегрузку, как показано выше.
Вольфюк
2
обновление: в MVC4 это больше не похоже на случай. ModelState.AddModelError ("", ex.Message); работы
Нил Томпсон
4
MVC5 Мне все еще нужно было вызвать ex.Message, чтобы заставить его работать.
Smiggleworth
спас день! У MVC5 все еще есть некоторые проблемы :)
juFo
67

Это работает лучше, так как вы можете показать validationMessage для указанного ключа:

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

и отобразить это так:

    @Html.ValidationMessage("keyName")
ingvesund
источник
28

Я знаю, что это старое и было отмечено как ответы с 147 голосами против, но есть еще кое-что, чтобы рассмотреть.

У вас могут быть все ошибки модели, как свойство name, так и string.Empty ключи, которые будут показаны в ValidationSummary, если вам нужно. Существует перегрузка в ValidationSummary, которая сделает это.

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

введите описание изображения здесь

Levitikon
источник
5
Да! Просто измените @Html.ValidationSummary(true, "", new { @class = "text-danger" })на@Html.ValidationSummary(false, "", new { @class = "text-danger" })
Xeningem
7

Может быть так:

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

И на дисплее добавить:

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

ИЛИ

<div class="alert alert-danger">
  @Html.ValidationSummary(false)
</div>
Петр Кнут
источник
5
@Html.ValidationSummary(false,"", new { @class = "text-danger" })

Использование этой строки может быть полезным

sachind
источник
Добавьте указанную выше строку в файл cshtml.
Sachind
2

В моем случае это не сработало из-за возврата.

Вместо того, чтобы использовать:

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

Я использовал:

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

Это модель, так что, очевидно, что ModelState.AddModelError("keyName","Message"); должна работать с моделью.

Этот ответ показывает, почему. Добавление проверки с DataAnnotations

Аллан Патрик Патцлафф
источник
0

Если почти все кажется правильным, еще одна вещь, на которую следует обратить внимание, это убедиться, что сводка проверки не скрыта явно с помощью некоторого переопределения CSS, например:

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

Это также может привести к тому, что они @Html.ValidationSummaryбудут отображаться скрытыми, поскольку сводка динамически отображается с validation-summary-validклассом.

Алекс
источник
0

Можешь попробовать,

<div asp-validation-summary="All" class="text-danger"></div>
Адрита Шарма
источник
примечание - это должен быть <div>, если это <span>, он не будет отображаться.
Стивен Энджелл
-4

ДОБАВЬТЕ это в самой нижней части вашего вида:

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

Ronit
источник