I Have the following register view
@model YFA.Models.RegisterViewModel
@{
ViewBag.Title = "Register";
}
<h2 class="col-md-offset-1">@ViewBag.Title</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-group">
<div class="row">
<div class="col-md-3 col-md-offset-1">
@Html.LabelFor(model => model.BranchId, htmlAttributes: new { @class = "control-label" })
@Html.DropDownListFor(model => model.BranchId, new SelectList(Model.Branches, "BranchId", "BranchName", 0), "Please Select", new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.BranchId, "", new { @class = "text-danger" })
</div>
</div>
</div>
<h3 class="col-md-offset-1">Name</h3>
<div class="form-group">
<div class="row">
<div class="col-md-3 col-md-offset-1">
@Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label" })
@Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @class = "form-control", placeholder = "John" } })
@Html.ValidationMessageFor(model => model.FirstName, "", new { @class = "text-danger" })
</div>
<div class="col-md-4">
@Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label" })
@Html.EditorFor(model => model.LastName, new { htmlAttributes = new { @class = "form-control", placeholder = "Smith" } })
@Html.ValidationMessageFor(model => model.LastName, "", new { @class = "text-danger" })
</div>
</div>
</div>
<h3 class="col-md-offset-1">Contact Details</h3>
<div class="form-group">
<div class="row">
<div class="col-md-4 col-md-offset-1">
@Html.LabelFor(model => model.Mobile, htmlAttributes: new { @class = "control-label" })
@Html.EditorFor(model => model.Mobile, new { htmlAttributes = new { @class = "form-control", placeholder = "07724 567890" } })
@Html.ValidationMessageFor(model => model.Mobile, "", new { @class = "text-danger" })
</div>
</div>
<div class="row">
<div class="col-md-3 col-md-offset-1">
@Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "control-label" })
@Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control", placeholder = "me@provider.com" } })
@Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" })
</div>
<div class="col-md-4">
@Html.LabelFor(model => model.ConfirmEmail, htmlAttributes: new { @class = "control-label" })
@Html.EditorFor(model => model.ConfirmEmail, new { htmlAttributes = new { @class = "form-control", placeholder = "me@provider.com" } })
@Html.ValidationMessageFor(model => model.ConfirmEmail, "", new { @class = "text-danger" })
</div>
</div>
</div>
<h3 class="col-md-offset-1">Dates</h3>
<div class="form-group">
<div class="row">
<div class="col-md-3 col-md-offset-1">
@Html.LabelFor(model => model.DateOfBirth, htmlAttributes: new { @class = "control-label" })
@Html.TextBoxFor(model => model.DateOfBirth, new { @class = "form-control", placeholder = "01/12/80" })
@Html.ValidationMessageFor(model => model.DateOfBirth, "", new { @class = "text-danger" })
</div>
<div class="col-md-2">
@Html.LabelFor(model => model.Joined, htmlAttributes: new { @class = "control-label" })
@Html.TextBoxFor(model => model.Joined, new { @class = "form-control", placeholder = "01/12/10" })
@Html.ValidationMessageFor(model => model.Joined, "", new { @class = "text-danger" })
</div>
</div>
</div>
<h3 class="col-md-offset-1">Password</h3>
<div class="form-group">
<div class="row">
<div class="col-md-3 col-md-offset-1">
@Html.LabelFor(model => model.Password, htmlAttributes: new { @class = "control-label" })
@Html.EditorFor(model => model.Password, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Password, "", new { @class = "text-danger" })
</div>
<div class="col-md-4">
@Html.LabelFor(model => model.ConfirmPassword, htmlAttributes: new { @class = "control-label" })
@Html.EditorFor(model => model.ConfirmPassword, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.ConfirmPassword, "", new { @class = "text-danger" })
</div>
</div>
</div>
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
<div class="col-md-offset-1 col-md-10">
<input type="submit" class="btn btn-default" value="Register" />
</div>
</div>
}
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
$(function () {
$("#DateOfBirth").datepicker({
format: "dd/mm/yyyy",
startDate: "-120y",
endDate: "-10y",
startView: 2,
calendarWeeks: true,
defaultViewDate: { year: 1975, month: 01, day: 01 }
});
});
$(function () {
$("#Joined").datepicker({
format: "dd/mm/yyyy",
startDate: "-20y",
endDate: "1y",
startView: 2,
calendarWeeks: true,
defaultViewDate: { year: 2010, month: 01, day: 01 }
});
});
</script>
}
The client side validation works fine for every field except the password field. it will warn if the password isn't the correct length but won't warn about the need for a capital or non alpha numeric character.
I'm using asp.net mvc identity.
The view model section for password is:
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
And the post controller is:
//
// POST: /Account/Register
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
var now = DateTime.Now;
UserManager.AddClaim(user.Id, new Claim(ClaimTypes.GivenName, model.FirstName));
//Add the new club details to the database
var Instructor = new Instructor
{
FirstName = model.FirstName,
LastName = model.LastName,
Joined = model.Joined,
Email = model.Email,
Mobile = model.Mobile,
BranchId = model.BranchId,
LGVDrv = model.LGVDrv,
MiniBusDrv = model.MiniBusDrv,
Operational = model.Operational,
ApplicationUserId = user.Id,
};
db.Instructors.Add(Instructor);
db.SaveChanges();
var currentUser = UserManager.FindByName(user.UserName);
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
return RedirectToAction("Index", "Home");
}
else
{
AddErrors(result);
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
When posting the form it returns the view because var result fair to succeed.
Following the comment above I amended the viewModel by adding a regular expression to it as follows:
[Required]
[RegularExpression(@"^(?=.*[A-Z])(?=.*[0-9])(?=.*[a-z].*[a-z].*[a-z]).{8,20}$",
ErrorMessage = "Password is not valid, it must be between 8 - 20 characters and contain a number and a capital letter")]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }