Duplicate entries issue while using multiple partial views in single page - asp.net-mvc

Hi I have two partial views in a single asp .net mvc page. When I submit entries using any of the partial view 2 entries got saved in database. If I disable any one partial view page works fine. Please help.
My Partial views look like this:
#using (Ajax.BeginForm("Create", "EnquiryForm", new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "divEnquiryFormMessage", LoadingElementId = "imgLoadingEnquiryForm" }))
{
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.AntiForgeryToken()
<div id="divEnquiryFormMessage">
</div>
<div class="form-group">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control", #placeholder = "Name" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "col-sm-12 text-danger" })
</div>
<div class="form-group">
#Html.EditorFor(model => model.ContactNumber, new { htmlAttributes = new { #class = "form-control", #placeholder = "Contact Number" } })
#Html.ValidationMessageFor(model => model.ContactNumber, "", new { #class = "col-sm-12 text-danger" })
</div>
<div class="form-group">
#Html.EditorFor(model => model.Email, new { htmlAttributes = new { #class = "form-control", #placeholder = "Email" } })
#Html.ValidationMessageFor(model => model.Email, "", new { #class = "col-sm-12 text-danger" })
</div>
<div class="form-group">
#Html.TextAreaFor(model => model.Comments, new { htmlAttributes = new { #class = "form-control", #placeholder = "Comments" } })
#Html.ValidationMessageFor(model => model.Comments, "", new { #class = "col-sm-12 text-danger" })
</div>
<button type="submit" class="submit_btn">Submit</button>
<img style="display:none;" src="~/Content/Images/LoadingImage.gif" id="imgLoadingEnquiryForm" />
}
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
Second partial view:
#using (Ajax.BeginForm("Create", "MailingList", new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "divMessage", LoadingElementId = "imgLoading" }))
{
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.AntiForgeryToken()
<div id="divMessage">
</div>
<div class="form-group">
#Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { #class = "form-control", #placeholder = "First Name" } })
#Html.ValidationMessageFor(model => model.FirstName, "", new { #class = "col-sm-12 text-danger" })
</div>
<div class="form-group">
#Html.EditorFor(model => model.LastName, new { htmlAttributes = new { #class = "form-control", #placeholder = "Last Name" } })
#Html.ValidationMessageFor(model => model.LastName, "", new { #class = "col-sm-12 text-danger" })
</div>
<div class="form-group">
#Html.EditorFor(model => model.Email, new { htmlAttributes = new { #class = "form-control", #placeholder = "Email" } })
#Html.ValidationMessageFor(model => model.Email, "", new { #class = "col-sm-12 text-danger" })
</div>
<div class="form-group">
#Html.EditorFor(model => model.ZipCode, new { htmlAttributes = new { #class = "form-control", #placeholder = "Zip Code" } })
#Html.ValidationMessageFor(model => model.ZipCode, "", new { #class = "col-sm-12 text-danger" })
</div>
<button type="submit" class="submit_btn">Submit</button><img style="display:none;" src="~/Content/Images/LoadingImage.gif" id="imgLoading" />
}
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
Both partial views are hitting different controllers and method still there is weird situation. I thing multiple "submit" buttons are causing problems, but I do not know how to resolve this issue.
Other ISSUE: after saving content I want to empty input controls in my partial view but it is also not working. I have tried ModelState.Clear()
My Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public string Create(EnquiryFormViewModel vObj)
{
System.Threading.Thread.Sleep(1000);
if (ModelState.IsValid)
{
EnquiryForm mObj = new EnquiryForm();
mObj.Name = vObj.Name;
mObj.ContactNumber = vObj.ContactNumber;
mObj.Email = vObj.Email;
mObj.Comments = vObj.Comments;
mObj.IsContacted = false;
mObj.CreatedOn = DateTime.Now;
string status = enquiryFormService.insertEnquiryForm(mObj);
ModelState.Clear();
return status;
}
else
{
return "<p class=\"bg-danger\">Oops there are some errors on page.</p>";
}
}

There Should Be Only 1 Ajax-unobtrusive in your whole page otherwise your controller will hit multiple times

You can use a success method after form have been submitted like this:-
#using (Ajax.BeginForm("Create", "MailingList", new AjaxOptions { onSuccess="ResetForm",HttpMethod = "POST", UpdateTargetId = "divMessage", LoadingElementId = "imgLoading" }))
And create a Function ResetForm() inside <script> tag and Inside function write
$('#formID')[0].reset();

Related

Editing cascading drop down list asp.net mvc 5

I have created a cascading dropdown list of category and subcategory
This is perfectly working when i create my product list it show both the option category and subcategory but
i am having a problem when i perform my Edit function on my edit page it shows category list but doesnt populate subcategory
thanks in advance
enter code here
This is view where you can see both category and subcategory dropdown list code
Create.cshtml
#model Masonic_Masoinc.Product
#{
ViewBag.Title = "Create";
}
<h2>Product</h2>
<h1>#ViewBag.IsSuccess</h1>
#using (Html.BeginForm("Create", "Home", FormMethod.Post, new { #class = "form-horizontal", enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.ProductName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ProductName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ProductName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ProductCode, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ProductCode, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ProductCode, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Price, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Price, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Price, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Image, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input type="file" name="file" value="file" />
#*#Html.EditorFor(model => model.Image, new { htmlAttributes = new { #class = "form-control" } })*#
#Html.ValidationMessageFor(model => model.Image, "", new { #class = "text-danger" })
</div>
</div>
<hr />
<h2>Category</h2>
<div class="form-group">
#Html.LabelFor(model => model.Categories.CategoryName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#if (ViewBag.CategoryList != null)
{
#Html.DropDownListFor(model => model.CatId, new SelectList(ViewBag.CategoryList, "CatId", "CategoryName"), "Select Your Category", new { #Class = "form-control" })
}
#*#Html.EditorFor(model => model.Category.CategoryName, new { htmlAttributes = new { #class = "form-control" } })*#
#Html.ValidationMessageFor(model => model.Categories.CategoryName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SubCategories.SubCategory, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.SubCatId, new SelectList(""), "Sub-Category", new { #class = "form-control" })
#*#Html.EditorFor(model => model.Category.CategoryName, new { htmlAttributes = new { #class = "form-control" } })*#
#Html.ValidationMessageFor(model => model.SubCategories.SubCategory, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
<script src="~/Scripts/jquery-3.4.1.min.js"></script>
<script>
$(document).ready(function () {
$("#CatId").change(function() {
$.get("/Home/GetSubCatList",
{ CatId: $("#CatId").val() },
function(data) {
$("#SubCatId").empty();
$.each(data,
function(index, row) {
$("#SubCatId")
.append("<option value='" + row.SubCatId + "'>" + row.SubCategory + "</option>");
});
});
});
});
</script>
this is action method in controller
controller
public JsonResult GetSubCatList(int catId)
{
MasonicMasterEntities db = new MasonicMasterEntities();
db.Configuration.ProxyCreationEnabled = false;
List<SubCategories> subcategory = db.SubCategories.Where(x => x.CatId == catId).ToList();
return Json(subcategory, JsonRequestBehavior.AllowGet);
}
Edit action method in conntroller
public ActionResult Edit(int id)
{
MasonicMasterEntities db = new MasonicMasterEntities();
var product = db.Product.SingleOrDefault(m => m.ProId == id);
if (product == null)
{
return HttpNotFound();
}
var category = db.Categories.ToList();
var subcategory = db.SubCategories.ToList();
var ViewModel = new ProductViewModel()
{
Products = product,
Categorieses = category,
SubCategorieses = subcategory
};
return View("Edit",ViewModel);
}

how to check if there is any html.ValidationMessageFor error or not in asp mvc?

How to check if validationMessageFor is empty?
#using (Html.BeginForm("ProfileSetting", "Home", FormMethod.Post, new { #id = "ProfileSetting" }))
{
<div class="container">
<button type="button" id="btn1" class="btn btn-primary btn-lg">Edit</button><br />
#Html.Label("Username : ")
#Html.EditorFor(model => model.Username, new { htmlAttributes = new { #class = "details1 form-control", #placeholder = "Example: Bond007", Type = "text", required = "true", disabled = "true" } })
#Html.ValidationMessageFor(model => model.Username, "", new { #class = "text-danger", #id = "username" })
<br />
#Html.Label("Email : ")
#Html.EditorFor(model => model.Email, new { htmlAttributes = new { #class = "details2 form-control", Type = "email", required = "true", disabled = "true" } })
#Html.ValidationMessageFor(model => model.Email, "", new { #class = "text-danger" ,id = "email" })
<br />
#Html.Label("Password : ")
#Html.EditorFor(model => model.Password, new { htmlAttributes = new { #class = "details3 form-control", #placeholder = "Example: Bond23!", Type = "password", required = "true", disabled = "true" } })
#Html.ValidationMessageFor(model => model.Password, "", new { #class = "text-danger" ,id="password" })
<br />
#Html.Label("Date of Birth : ")
#Html.EditorFor(model => model.DateOfBirth, "{0:dd-MM-yyyy}", new { htmlAttributes = new { #class = "details4 form-control" ,#placeholder="DD-MM-YYYY",Type = "text", required = "true", disabled = "true" } })
#Html.ValidationMessageFor(model => model.DateOfBirth, "", new { #class = "text-danger", id = "dob" })
<br />
#Html.Label("Phone No : ")
#Html.EditorFor(model => model.PhoneNo, new { htmlAttributes = new { #class = "details5 form-control", Type = "number", #placeholder = "Phone No", required = "true", disabled = "true" } })
#Html.ValidationMessageFor(model => model.PhoneNo, "", new { #class = "text-danger", id = "phoneno" })
<br />
<label id="Successfully_Changed"></label>
<button type="button" id="btnSave" class="btn btn-primary btn-lg">Save</button>
<br />
</div>
}
In Script:
$('#btnSave').click(function () {
#{
if (!String.IsNullOrEmpty(#Html.ValidationMessageFor(u=>u.Username).ToString()))
{
<text>
alert($('#ProfileSetting').validate().valid());
$.post(
"/Home/EditProfile",
{
Username: $('.details1').val(),
Password: $('.details3').val(),
DateOfBirth: $('.details4').val(),
PhoneNo: $('.details5').val(),
}
);
$('#Successfully_Changed').html("Successfully Changed.");
$('#Successfully_Changed').show();
</text>
} }
});
In one of the comments, to your question you said:
To make a ajax call to the controller if it doesn't have any error than to hide the save button and save the data in h field in the database and disabling the field.
If that is your goal to check if the form is valid before you make an ajax call, then this is the way to do it:
var form = $( "#formId" );
form.validate();
if (form.valid()){
// All is good so do your ajax operation.
}
The valid() method:
Checks whether the selected form is valid or whether all selected elements are valid.

how to pass an object to specific view with ASP.net MVC

I have a page wich it has a form and everythings works correctly.
my question is for when my model state is not valid, then how to return contact us to index view not create view
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,Name,Email,Phone,Message,Date")] Contact_US contact_US)
{
if (ModelState.IsValid)
{
db.Contact_US.Add(contact_US);
db.SaveChanges();
MailMessage mail = new MailMessage();
mail.To.Add("");
mail.From = new MailAddress("");
mail.Subject = contact_US.Email;
string body = contact_US.Message;
mail.Body = "Phone:" + contact_US.Phone + "<br />Name:" + contact_US.Name +"<br />Email:"+contact_US.Email+ "<br /><br />" + body;
mail.IsBodyHtml = true;
SmtpClient smtp = new SmtpClient();
smtp.Host = "smtp.gmail.com";
smtp.Port = 587;
smtp.UseDefaultCredentials = false;
smtp.Credentials = new System.Net.NetworkCredential
("", "");// Enter seders User name and password
smtp.EnableSsl = true;
smtp.Send(mail);
TempData["ResultMessage"] = "Thank you for your enquiry and or enrolment. we will attend to this submission and come back to you soon";
TempData["TimeMessage"] = "Your entry was received on"+DateTime.Now;
return RedirectToAction("Index");
}
return View(contact_US);
}
in this situation if model state is not valid it looks fore create view but i don't want to have a create view . I just want to bring contact us to index page.
this is my index view
#using (Html.BeginForm("Create", "Contact_Us", FormMethod.Post, new { #id = "contactusform" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2 txtformat" })
<div class="col-md-12">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Email, htmlAttributes: new { #class = "control-label col-md-2 txtformat" })
<div class="col-md-12">
#Html.EditorFor(model => model.Email, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Email, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Phone, htmlAttributes: new { #class = "control-label col-md-2 txtformat" })
<div class="col-md-12">
#Html.EditorFor(model => model.Phone, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Phone, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group hidden">
#Html.LabelFor(model => model.Date, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Date, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Date, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Message, htmlAttributes: new { #class = "control-label col-md-2 txtformat" })
<div class="col-md-12 contactusmsg">
#Html.TextAreaFor(model => model.Message, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Message, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group contactuspostbtn">
<div class="col-md-12">
<input id="postcontactusmessage" type="submit" value="Send" class="btn btn-default" />
</div>
</div>
</div>
}
Appreciate Any help
If you just want to call a view and pass in correct model then you can use overload with view name as in below cases:
Load view with Model:
return View("Index", contact_US); //Index is View name and contact_US is the Model.
Load view without Model:
return View("Index");
Make sure the Model expected by the view and what you are passing from the action are matching.
Ideally, except some specific cases better to stay close to MVC practices. Ex: If user provided data from Contact page then it would be nice and easily understood to redirect them back to Contact page instead of some other page. This need lot of caution especially while renaming the views etc.
Hope this help you.

Passing form input from view to controller

I'm working with a standard razor view with form data. I want to pass the input form data to my controller after pressing the submit button. My view looks like this:
#model CareSource.ReleaseAssistant.Models.Prime.Team
#{
ViewBag.Title = "Create";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Create New Team</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Team</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Abbreviation, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Abbreviation, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Abbreviation, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CreatedBy, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.CreatedBy, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.CreatedBy, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CreatedOn, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.CreatedOn, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.CreatedOn, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ModifiedBy, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ModifiedBy, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ModifiedBy, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ModifiedOn, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ModifiedOn, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ModifiedOn, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
The problem is that the information in the form is not being passed back to my controller to be handled by my action method. I'm trying create a new entry in my database using web api. My action method looks like this:
[HttpPost]
public ActionResult Create(FormCollection collection)
{
try
{
if (ModelState.IsValid)
{
HttpEndPointContext httpEndPoint = new HttpEndPointContext()
{
AuthenticationMethod = HttpAuthenticationMethods.None,
Ssl = false,
HttpMethod = HttpMethod.Post,
//Path = "localhost:32173/api/team/",
QueryStrings = null,
};
IProcessResult result = HttpConnectionManager.Current.SendMessage(httpEndPoint);
var response = result.ResponseData.ToString();
}
return RedirectToAction("Index");
}
catch
{
return View();
}
}
Most of the code in this project was generated using Codesmith Generator and uses the MicroORM called PetaPoco.
Since your form is strongly typed to an instance of Team and you are using that to generate the input form fields, you can use Team object as the parameter of your HttpPost method.
HttpPost]
public ActionResult Create(Team model)
{
if (ModelState.IsValid)
{
//access model.Properties
}
return View(model);
}
Do use Team model as parameter remove formCollection and try
Please update your View with the given code :
#using (Html.BeginForm("Create", "YourControllerName", FormMethod.Post, new { id = "form" }))
{
//Copy your current code as it is here.
}

Client side validation not working on password

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

Resources