Search code examples
c#asp.net-mvcmodel-validation

ASP.NET Core MVC Model Validation Errormessage not showing


I am trying to validate the input of the user. The validation works, because in my controller method the ModelState.IsValid is false when some input is invalid and is true when some input is valid.

The problem that I am having now is that the errormessage is not showing to the user. I thought that the empty string in the @Html.ValidationMessageFor should be automatically filled in by the error. That is correct, right? The same code worked for my registration form, but not here.

Here is my form code:

@using (Html.BeginForm("ChangeProfile", "Account", FormMethod.Post))
{
<div class="form-group">
    <label class="col-lg-3 control-label">Name:</label>
    <div class="col-lg-9">
        @Html.TextBoxFor(n => n.Name, new { @class = "form-control form-control-custom" })
        @Html.ValidationMessageFor(n => n.Name, "", new { @class = "text-danger" })
    </div>
</div>

<div class="form-group">
    <label class="col-lg-3 control-label">Email:</label>
    <div class="col-lg-9">
        <input disabled class="form-control form-control-custom" type="text" value="@Model.Email" />
    </div>
</div>

<div class="form-group">
    <label class="col-lg-3 control-label">New Password:</label>
    <div class="col-lg-9">
        @Html.TextBoxFor(n => n.Password, new { type = "password", placeholder = "New Password", @class = "form-control form-control-custom" })
        @Html.ValidationMessageFor(n => n.Password, "", new { @class = "text-danger" })
    </div>
</div>

<div class="form-group">
    <label class="col-lg-3 control-label">Confirm New Password:</label>
    <div class="col-lg-9">
        @Html.TextBoxFor(n => n.ConfirmPassword, new { type = "password", placeholder = "Confirm New Password", @class = "form-control form-control-custom" })
        @Html.ValidationMessageFor(n => n.ConfirmPassword, "", new { @class = "text-danger" })
    </div>
</div>

<div class="form-group">
    <label class="col-lg-3 control-label">Phone Number:</label>
    <div class="col-lg-9">
        @Html.TextBoxFor(n => n.PhoneNumber, new { @class = "form-control form-control-custom" })
        @Html.ValidationMessageFor(n => n.PhoneNumber, "", new { @class = "text-danger" })
    </div>
</div>

<div class="form-group">
    @Html.ActionLink("DELETE ACCOUNT", "DeleteProfile", Model, new { @class = "btn btn-delete bg-primary" })
    <input type="reset" class="btn btn-default" value="Cancel" style="float: right; margin-right: 15px;">
    <input type="submit" class="btn btn-primary btn-custom" style="margin-right: 10px;" value="Save Changes">
</div>
}

Here is my controller method:

public IActionResult ChangeProfile(ProfileViewModel profileViewModel)
    {
        if (!ModelState.IsValid)
        {
            return RedirectToAction("Profile");
        }
            return View("Overview", accountService.ChangeProfile(profileViewModel));
    }

And here is my ProfileViewModel:

public class ProfileViewModel
{
    [Required]
    public string Name { get; set; }

    public string Email { get; set; }

    [DataType(DataType.Password)]
    public string Password { get; set; }

    [DataType(DataType.Password)]
    [Compare("Password", ErrorMessage = "The passwords do not match.")]
    public string ConfirmPassword { get; set; }

    [Required(ErrorMessage = "The Phone Number field is required.")]
    [Phone(ErrorMessage = "The Phone Number field is not a valid phone number.")]
    public string PhoneNumber { get; set; }
}

Solution

  • It's because when the model state is not valid you are doing a redirection with RedirectToAction("Profile"). By doing that you are loosing the "context" .

    You should just re-render the View . With something like that :

    return View("yourView", profileViewModel);
    

    take care that your "view model" is not missing some properties (properties that are not in your form). If it is the case you must rebuild your viewmodel.