Lars Holdgaard
Lars Holdgaard

Reputation: 9976

Html.ValidationMessage is empty despite message added to ModelState

I am trying to use the ModelState.AddErrrorModel and Html.ValidationMessage("Account") together, to show an error message.

However, even though I can debug the model error is being added on my POST, I cannot see it on the view when the view is loaded again.

Code run on POST from the form, where I can see the ModelState.AddModelError is being called (ex.Message do have a value as well):

            try {
               // code that fails in this case
            }
            catch (Exception ex)
            {
                logger.Error(ex);
                ModelState.AddModelError("Register",ex.Message);
            }

            return RedirectToAction("Account", accountViewModel);

My view looks like this:

 <h3>Get your free account now</h3>
        @using (Html.BeginForm("Register", "Home", FormMethod.Post, new { @class = "form" }))
        {
            // trying to test different methods to get my errors... NOTHING works :)
            @Html.ValidationSummary()
            @Html.ValidationMessage("Register")
            @Html.BusinessErrorMessageBox()


            <div class="form-group">
                <label>Email address</label>
                @Html.TextBoxFor(m => m.RegisterViewModel.Email, new { @class = "form-control", placeholder = "Email", @type = "email" })
                @Html.ValidationMessageFor(m => m.RegisterViewModel.Email)
            </div>
            <div class="form-group">
                <label>Password</label>
                @Html.PasswordFor(m => m.RegisterViewModel.Password, new { @class = "form-control", placeholder = "Password" })
                @Html.ValidationMessageFor(m => m.RegisterViewModel.Password)
            </div>
            <div class="form-group">
                <label>Your country (the country where you live or where your organization is registered in)</label>
                @Html.DropDownListFor(model => model.RegisterViewModel.SelectedCountry, Model.RegisterViewModel.Countries, new { @class = "form-control" })
            </div>
            <input type="submit" class="btn btn-primary btn-lg" value="Get your free account now" />
        }

For practical reasons, my view is called Account, and the method accepting the POST, is called "Register".

But no matter what I do, there is no errors being shown in either the ValidationMessage or ValidationSummary.

Any idea what I am doing wrong?

EDIT:

FYI: there are two forms in the view, if that might have an influrence.

EDIT 2:

I can see the following HTML is being outputted when clicking the button that goes to my server. The value ex.Message, shows nowhere:

<div class="validation-summary-valid" data-valmsg-summary="true"><ul><li style="display:none"></li>
</ul></div><span class="field-validation-valid" data-valmsg-for="Business" data-valmsg-replace="true"></span><span class="field-validation-valid" data-valmsg-for="Register" data-valmsg-replace="true"></span>     

Upvotes: 1

Views: 695

Answers (2)

Daniel J.G.
Daniel J.G.

Reputation: 35002

The result from your POST action is always a redirect:

return RedirectToAction("Account", accountViewModel);

That means your error messages will be lost, since the redirect will tell the browser to send another GET request for the Account action, where you will render a fresh Register view with no errors.

The flow that you want is:

  • POST logic succeeds, return a redirect to Account, which in turn will send a GET request
  • POST logic fails, return the same view so errors can be displayed

Your POST method would look something like this:

try {
    //your logic here

    //Everything worked, return a redirect
    return RedirectToAction("Account", accountViewModel);
}
catch (Exception ex)
{
    logger.Error(ex);
    ModelState.AddModelError("Register",ex.Message);
}

//If we get here, something went wrong. Return the view so errors are displayed
return View("Account", accountViewModel);

Hope it helps!

Upvotes: 1

Actually, what you want is:

@Html.ValidationSummary(false)

You want all errors shown on the form: reference. Since you are not attaching the model error to a specific property, the error is not shown on any form element validation.

Upvotes: 0

Related Questions