Check If username/email already registered using Remote Validation attribute in asp.net mvc
When we create Registration form on a web application, we have to check that the email address and username that user is entering is unique and is not already. In asp.net mvc we have Validation Attribute feature in under System.ComponentModel.DataAnnotations and System.Web.Mvc which we can use for different type of Validations before sending data to be saved in persistent location.
In System.Web.Mvc we have Remote attribute which is available in asp.net mvc 4 in which i am implementing it for this post, i am not sure if it is available in the earlier version of asp.net mvc.
So i have this ViewModel:
In System.Web.Mvc we have Remote attribute which is available in asp.net mvc 4 in which i am implementing it for this post, i am not sure if it is available in the earlier version of asp.net mvc.
So i have this ViewModel:
public class SignUpViewModel { public int UserID { get; set; } [Required(ErrorMessage = "First Name is required")] public string FirstName { get; set; } [Required(ErrorMessage = "Last Name is Required")] public string LastName { get; set; } [Required(ErrorMessage = "Username is Required")] [RegularExpression(@"^[a-zA-Z0-9]+$", ErrorMessage = "user name must be combination of letters and numbers only.")] public string UserName { get; set; } [Required(ErrorMessage = "Password is Required")] public string Password { get; set; } [Required(ErrorMessage = "Password is Required")] [System.Web.Mvc.Compare("Password",ErrorMessage="Both Password fields must match.")] public string ConfirmPassword { get; set; } [Required(ErrorMessage = "Email Address is required")] [EmailAddress(ErrorMessage = "Invalid Email Address")] public string Email { get; set; } }
As you can see there are laready attributes on the properties of ViewModel like Required which are mandatory fields, RegularExpression attribute for Email Address format validation and Compare attribute for comparing two properties values which is useful here for Password and Repeat Password textbox for making sure that user has verified what password he is setting.
Now what will happen if user enters a username or Email Address which is already registered, one way is to check in post action for username and Email Address and show user error message that username or Email Address is already taken which does not looks though, as validation should be done before posting data to action using unobtrusive validtion.
Now here we will use Remote attribute which will check for both UserName and Email Address field, here is how it will be done:
[Required(ErrorMessage = "Username is Required")] [RegularExpression(@"^[a-zA-Z0-9]+$", ErrorMessage = "user name must be combination of letters and numbers only.")] [Remote("UsernameExists","Account",HttpMethod="POST",ErrorMessage="User name already registered.")] public string UserName { get; set; } [Required(ErrorMessage = "Email Address is required")] [EmailAddress(ErrorMessage = "Invalid Email Address")] [Remote("EmailExists", "Account", HttpMethod = "POST", ErrorMessage = "Email address already registered.")] public string Email { get; set; }
Remote Attribute has different parameters to be specified:
- Action Name which will be called which will have input parameter for this property value
- Controller Name of which action will be executed
- HttpMethod (Get or Post)
- ErrorMessage (Error Message that will be displayed if validation fails)
Here is the action code:
public JsonResult UsernameExists(string username) { return Json(!String.Equals(username,"ehsansajjad",StringComparison.OrdinalIgnoreCase)); } public JsonResult EmailExists(string email) { return Json(!String.Equals(email, "ehsansajjad@yahoo.com", StringComparison.OrdinalIgnoreCase)); }
Here is the complete View code:
@model CustomValidationMessageHelper.ViewModels.SignUpViewModel @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>SignUp</title> <link href="@Url.Content("~/Content/jquery.qtip.css")" rel="stylesheet" /> <script src="@Url.Content("~/Scripts/jquery-1.9.1.js")"></script> <script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")"></script> <script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/jquery.qtip.min.js")" type="text/javascript"></script> </head> <body> <div> @using (Html.BeginForm("SignUp", "Account", FormMethod.Post, new { @class = "form-inline", role = "form" })) { @Html.AntiForgeryToken() <div class="row"> <div class="span8 offset5 aui-page-panel"> <div> <h2>Sign Up</h2> </div> <fieldset style="margin-bottom: 40px;"> <legend style="border-bottom: 1px solid gray; font-size: 16px;">Basic Information</legend> <table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr id="tr_basic"> <td style="vertical-align: top;" width> <div id="basicinfo" style="width: 100%"> <div style="height: auto !important; overflow-y: visible;"> <table cellpadding="3"> <tbody> <tr> <td width="150"> @Html.LabelFor(model => model.FirstName, new { @class = "sr-only" }) </td> <td> @Html.TextBoxFor(model => model.FirstName, new { @class = "form-control input-sm" }) @Html.ValidationMessageFor(model => model.FirstName) </td> </tr> <tr> <td> @Html.LabelFor(model => model.LastName) </td> <td> @Html.TextBoxFor(model => model.LastName, new { @class = "input-xsmall" }) @Html.ValidationMessageFor(model => model.LastName) </td> </tr> <tr> </tr> </tbody> </table> </div> </td> </tr> </table> <legend style="border-bottom: 1px solid gray; font-size: 16px;">Account Information</legend> <table cellpadding="5"> <tr> <td width="150"> @Html.LabelFor(model => model.UserName) </td> <td> @Html.TextBoxFor(model => model.UserName) @Html.ValidationMessageFor(model => model.UserName) </td> <td id="tdValidate"> <img id="imgValidating" src="@Url.Content("~/Images/validating.gif")" style="display:none;" /></td> </tr> <tr> <td> @Html.LabelFor(model => model.Password) </td> <td> @Html.PasswordFor(model => model.Password) @Html.ValidationMessageFor(model => model.Password) </td> </tr> <tr> <td> @Html.LabelFor(m => m.ConfirmPassword, new { @class = "control-label" }) </td> <td> @Html.PasswordFor(model => model.ConfirmPassword) @Html.ValidationMessageFor(model => model.ConfirmPassword) </td> </tr> <tr> <td> @Html.LabelFor(m => m.Email, new { @class = "control-label" }) </td> <td> @Html.TextBoxFor(model => model.Email) @Html.ValidationMessageFor(model => model.Email) </td> </tr> <tr> <td> <p> <div class="control-group"> <div class="controls"> <input id="btnRegister" type="submit" class="btn btn-primary" value="Register" /> </div> </div> </p> </td> <td></td> </tr> </table> </div> </div> } </div> </body> </html>
Now when i will enter username "ehsansajjad" or Email Address "ehsansajjad@yahoo.com" validation will get fired that user already exists :
You can download the sample project from here.