ASP.NET MVC Html.ValidationSummary(true) does not display model errors
Asked Answered
C

10

199

I have some problem with Html.ValidationSummary. I don't want to display property errors in ValidationSummary. And when I set Html.ValidationSummary(true) it does not display error messages from ModelState. When there is some Exception in controller action on string

MembersManager.RegisterMember(member);

catch section adds an error to the ModelState:

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

But ValidationSummary does not display this error message. When I set Html.ValidationSummary(false) all messages are displaying, but I don't want to display property errors. How can I fix this problem?

Here is the code I'm using:

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

Controller:

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

View:

<% 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)%>
<% } %>
Cardoza answered 12/5, 2010 at 11:15 Comment(0)
O
334

I believe the way the ValidationSummary flag works is it will only display ModelErrors for string.empty as the key. Otherwise it is assumed it is a property error. The custom error you're adding has the key 'error' so it will not display in when you call ValidationSummary(true). You need to add your custom error message with an empty key like this:

ModelState.AddModelError(string.Empty, ex.Message);
Overbear answered 12/5, 2010 at 13:26 Comment(5)
@LordCover: I'm guessing this is "working as designed" and not a bug - the overload of ValidationSummary() used by default excludes ModelState errors associated with the properties of the model itself. This leaves those errors to be represented by Html.ValidationMessageFor() calls for each individual property without having them duplicated in the summary. That in mind, it appears that any model error added with a non-empty key is assumed to be associated with a model property, even if the key doesn't match the name of a property.Choose
Just a note for other implementers: ModelState.AddModelError(string.Empty, ex); doesn't seem to work either. You must use the ModelState.AddModelError(string, string) overload as shown above.Tourane
update: In MVC4 this no longer seems to be the case. ModelState.AddModelError("", ex.Message); worksButcher
MVC5 I still needed to call the ex.Message to get it to work.Englishism
first parameter to ValidationSummary methos is excludePropertyErrors set it to fase it will start showing model errors, otherwise setting key parameter of AddModelErros method to string.empty will show custom error messages.Headley
E
69

This works better, as you can show validationMessage for a specified key:

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

and display it like this:

    @Html.ValidationMessage("keyName")
Eldaelden answered 27/2, 2013 at 11:55 Comment(0)
F
28

I know this is kind of old and has been marked as answers with 147 up votes, but there is something else to consider.

You can have all the model errors, the property named and string.Empty keys alike, be shown in the ValidationSummary if you need to. There is an overload in the ValidationSummary that will do this.

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

enter image description here

Fugato answered 13/11, 2013 at 22:50 Comment(1)
Yes! Just change @Html.ValidationSummary(true, "", new { @class = "text-danger" }) to @Html.ValidationSummary(false, "", new { @class = "text-danger" })Carlyncarlynn
E
9

Maybe like that:

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

And in display add:

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

OR

<div class="alert alert-danger">
  @Html.ValidationSummary(false)
</div>
Earring answered 12/10, 2014 at 14:4 Comment(0)
C
6
@Html.ValidationSummary(false,"", new { @class = "text-danger" })

Using this line may be helpful

Charette answered 31/12, 2018 at 4:43 Comment(1)
Add th above line in cshtml file.Charette
T
3

In my case it was not working because of the return.

Instead of using:

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

I used:

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

It´s a Model, so it is obvius that ModelState.AddModelError("keyName","Message"); must work with a model.

This answer show why. Adding validation with DataAnnotations

Triangulation answered 27/9, 2014 at 23:43 Comment(0)
H
0

If nearly everything seems right, another thing to look out for is to ensure that the validation summary is not being explicitly hidden via some CSS override like this:

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

This may also cause the @Html.ValidationSummary to appear hidden, as the summary is dynamically rendered with the validation-summary-valid class.

Helmand answered 12/5, 2015 at 20:37 Comment(0)
S
0

You can try,

<div asp-validation-summary="All" class="text-danger"></div>
Sherbet answered 30/8, 2019 at 19:34 Comment(1)
note - this has to be a <div>, if it's a <span> it won't render.Ukulele
B
0

use can use bellow lines

    @if (!ViewData.ModelState.IsValid)
                {
                    @Html.ValidationSummary("", new { @class = "alert alert-warning alert-dismissible fade show" })
                }

and for each field use somthing like this:

                    @Html.ValidationMessageFor(m => m.Email, null, new { @class = "field-validation-error " })
Bestride answered 10/12, 2021 at 9:13 Comment(0)
F
-5

ADD it in the lowermost part og your View:

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

Famagusta answered 6/4, 2015 at 10:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.