On some of our web applications, we require users to register our site in order to perform some special actions. This feature kind of a no-brainer thing thanks to built-in ASP.NET Membership API. It works well with either ASP.NET Web Forms or ASP.NET MVC. In this path, on some cases, we also require each users to have unique username or unique e-mail. The implementation of this feature also does not require our concern either.
Let’s see it in action what I am getting at here.
I created an ASP.NET MVC 3 Web Application project with Visual Studio 2010 (It is also same for Visual Web Developer which is a free version of Visual Studio) and I fired it up by clicking Ctrl + F5. When I navigate to /Account/Register, I get the following view :
In order to stick with the topic here, I already registered a user with a username of user1. Look what happens when I try to create another user with a username of user1 :
So, the thing ASP.NET offers us out of the box is clever. But there is a little bit a problem here. Well, not a problem but how can I call it, hmmm… I can say lack of creativeness. When I push the register button here, it goes all the way to server to register the user. Inside our controller, built-in register action checks if user already exists or not.
Wouldn’t it be nice if user instantly sees if typed username is valid or not? It certainly would be!
Introduction to ASP.NET MVC Remote Validation
We know that ASP.NET MVC takes advantage of .NET Framework Data Annotations to validate user’s input. By this way, we can check for required fields with RequiredAttribute, length of a string with StringLengthAttribute and so on. Well, it turns out that there is another useful one called RemoteAttribute which we can use, for example, to validate e-mail and username in a registration form and alert the user before the form is posted.
This Remote Validation thing is what we are looking for. In order to implement this for our scenario, we need to tweak the UserName property of RegisterModel class. Here is the whole RegisterModel class after the modification I made :
public class RegisterModel { [Required] [Display(Name = "User name")] [Remote("doesUserNameExist", "Account", HttpMethod = "POST", ErrorMessage = "User name already exists. Please enter a different user name.")] public string UserName { get; set; } [Required] [DataType(DataType.EmailAddress)] [Display(Name = "Email address")] public string Email { get; set; } [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; } [DataType(DataType.Password)] [Display(Name = "Confirm password")] [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] public string ConfirmPassword { get; set; } }
As you can see, we added Remote attribute for UserName property inside RegisterModel class. RemoteAttribute has several overloads but what we entered here is as follows :
How our controller action doesUserNameExist looks like is as follows :
[HttpPost] public JsonResult doesUserNameExist(string UserName) { var user = Membership.GetUser(UserName); return Json(user == null); }
As you see, it is a simple controller action which returns JsonResult. What we need to notice here is UserName paramater of this action. We put that parameter there to pick up the user input which will be sent through Ajax request to our action. Remote Validation will send the user input as Form Data which will have the same name as property. So, in this case it is UserName.
Before we give it a try, make sure that you have the following libraries referenced on your registration page :
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
Let’s build our project and fire it up to see it in action.
1. I loaded the page :
2. I enter user1 for UserName field (user1 is the username which is already inside our database) :
3. Then I just put the mouse cursor inside another text input field and see what happened :
Just what we needed. I thought showing this in action like that is a lame approach to do that so I recorded a short video in order to demonstrate this. In this video I also tried to show what is happening behind the scenes. See it below :
I also put the sample project on GitHub so you can get the working sample code if you want :
https://github.com/tugberkugurlu/MvcRemoteValidationSample
Note :
But there is a donwside for this validation attribute. The remote validation does not validate the user input on server side. So, you need to make sure on the server side that it is valid as it is being done on our sample. We also make sure on the server side that username which is being passed to our controller is unique.
Hope this will help you even a little bit.