User987 User987 - 1 month ago 15
C# Question

Unable to display MVC 5 validation error messages on view

I have a specific problem using MVC 5 validation to display error messages if the user hasn't properly entered everything on the page. The HTML markup of the form is as following:

@using (Html.BeginForm("RegisterDo", "User", FormMethod.Post))
{
<div>
@Html.ValidationMessageFor(model => model.FirstName)
@Html.TextBoxFor(m => m.FirstName, new { placeholder = "First name", @class = "form-control", @type = "text" })



</div>
<div>
@Html.ValidationMessageFor(model => model.LastName)
@Html.TextBoxFor(m => m.LastName, new { placeholder = "Last name", @class = "form-control", @type = "text" })


</div>
<div>
@Html.ValidationMessageFor(model => model.Email)
@Html.TextBoxFor(m => m.Email, new { placeholder = "Email", @class = "form-control", @type = "email" })

</div>
<div>
@Html.ValidationMessageFor(model => model.Password)
@Html.TextBoxFor(m => m.Password, new { placeholder = "Password", @class = "form-control", @type = "password" })

</div>
<div>
@Html.ValidationMessageFor(model => model.PasswordConfirm)
@Html.TextBoxFor(m => m.PasswordConfirm, new { placeholder = "Confirm password", @class = "form-control", @type = "password" })


</div>
<div>
@Html.ValidationMessageFor(model => model.SelectedCountryId)
@Html.DropDownListFor(model => model.SelectedCountryId, Model.Countries, "-- Please select a country --", new { @class = "select2_single form-control select2-hidden-accessible", @tabindex = "-1" })

</div>
<div>
<input class="btn btn-default submit" type="submit" value="Register" />
</div>
}


Please note that I have a dropdown list that I need to fill initially when the view is rendered (i.e. I have to pass the countries list onto the view in order to render it properly). The issue that I have here is that when I click the "register" button, the code from my action isn't triggered AT ALL. Instead I simply get the URL in my browser as following:

http://localhost:60617/user/register?FirstName=&LastName=&Email=&Password=&PasswordConfirm=&SelectedCountryId=


And the error messages are not displayed at all... The code isn't triggered at all...

These are my two actions:

[HttpPost]
[ActionName("Register")]

public ActionResult DoRegister(UserRegistrationViewModel model)

{
if (ModelState.IsValid)
{
var user = new Users();
user.FirstName = model.FirstName;
user.LastName = model.LastName;
user.Email = model.Email;
user.PasswordSalt = Helpers.PasswordHelper.CreateSalt(40);
user.PasswordHash = Helpers.PasswordHelper.CreatePasswordHash(model.Password, user.PasswordSalt);
user.CountryId = Convert.ToInt32(model.SelectedCountryId);
user.Active = true;
Connection.ctx.Users.Add(user);
Connection.ctx.SaveChanges();
var role = new UserRoles();
role.RoleId = 2;
role.UserId = user.UserId;
role.Active = true;
user.UserRoles.Add(role);
Connection.ctx.SaveChanges();
return RedirectToAction("Success");
}
else
{
return View("Register", model);
}
}
public ActionResult Register()
{
var model = new UserRegistrationViewModel();
var countries = Connection.ctx.Countries.OrderBy(x => x.CountryName).ToList();
model.Countries = new SelectList(countries, "CountryId", "CountryName");
return View(model);
}


First action is responsible for rendering the view, and second one is responsible for logic when the user registers...

What am I doing wrong here. I'm missing out something very obvious here, but I just cant see it... :(

Edit here is the ViewModel:

public class UserRegistrationViewModel
{
[Required(ErrorMessage = "First name is required!")]
public string FirstName { get; set; }

[Required(ErrorMessage = "Last name is required!")]
public string LastName { get; set; }

[Required(ErrorMessage = "Email name is required!")]
public string Email { get; set; }

[Required(ErrorMessage = "Password name is required!")]
public string Password { get; set; }

[Required(ErrorMessage = "Password confirmation name is required!")]
public string PasswordConfirm { get; set; }
[Required(ErrorMessage = "Country needs to be selected!")]
public int SelectedCountryId { get; set; }


public SelectList Countries { get; set; }
}

SeM SeM
Answer

Add [ActionName("Register")] attribute to your post method:

[HttpPost]
[ActionName("Register")]
public ActionResult RegisterDo(UserRegistrationViewModel model)
{
    if (ModelState.IsValid)
    {
        var user = new Users();
        user.FirstName = model.FirstName;
        user.LastName = model.LastName;
        user.Email = model.Email;
        user.PasswordSalt = Helpers.PasswordHelper.CreateSalt(40);
        user.PasswordHash = Helpers.PasswordHelper.CreatePasswordHash(model.Password, user.PasswordSalt);
        user.CountryId = Convert.ToInt32(model.SelectedCountryId);
        user.Active = true;
        Connection.ctx.Users.Add(user);
        Connection.ctx.SaveChanges();
        var role = new UserRoles();
        role.RoleId = 2;
        role.UserId = user.UserId;
        role.Active = true;
        user.UserRoles.Add(role);
        Connection.ctx.SaveChanges();
        return RedirectToAction("Success");
    }
    else
    {
        return View(model);
    }
}