Check Instantly If Username Exists - ASP.NET MVC Remote Validation

This blog post will walk you through on implementation and usage of ASP.NET MVC Remote Validation. As a sample, we will validate the availability of the username for membership registration.
2011-10-19 07:07
Tugberk Ugurlu


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 :

image

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 :

image

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 :

  • doesUserNameExist : It is the name of the Action which will validates the user input by returning true or false as JSON format. We will see how we do that in a minute.
  • Account : It is the name of the controller which doesUserNameExist lives in.
  • HttpMethod : Simply we are telling the remote validation to communicate our mini service over Http POST method (This is not required but I’d like to do it this way).

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 :

image

2. I enter user1 for UserName field (user1 is the username which is already inside our database) :

image

3. Then I just put the mouse cursor inside another text input field and see what happened :

image

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.



Comments

Justin Schwartzenberger
by Justin Schwartzenberger on Wednesday, Oct 19 2011 19:03:09 +03:00

That is super slick! Nice write up. Good idea tossing the video up there at the end.

tugberk
by tugberk on Wednesday, Oct 19 2011 22:35:21 +03:00

@Justin 

Thanks, I liked that you liked that :)

I couldn't figure out any other way to show this up in action so I recorded a short vidoe. I added some spice inside the video as well:)

Frans Stridh
by Frans Stridh on Tuesday, Oct 25 2011 09:17:19 +03:00

Thanks for this post. Really nice. I implemented it straight away :)

 

I also shared this link on twitter. I am really enjoying your blog posts!

Rick Anderson {MSFT}
by Rick Anderson {MSFT} on Saturday, Oct 29 2011 03:06:11 +03:00

Video is nice. I have this exact topic on MSDN at http://msdn.microsoft.com/en-us/library/gg508808(VS.98).aspx 

I use fiddler rather than Chrome dev tools.

Tugberk
by Tugberk on Saturday, Oct 29 2011 10:05:12 +03:00

@Rick

Yeah, I have just seen that one. Indeed, exatly the same topic. To be honest I have cheated a little bit from the books while I was writing this:)

I am having problems with fiddler nowadays so I had to use Chrome developer tools :s

Reju
by Reju on Wednesday, Apr 11 2012 12:04:13 +03:00

Hi,

 

what is Remote here ?

i have similier requirements but how can i create remote class?

which namespace we need for using remote ?

Rikin
by Rikin on Tuesday, May 22 2012 08:00:25 +03:00

nice article thks....

 

but if want to do on somethig if return true then how can do it... pls help me...

jonathan reed
by jonathan reed on Thursday, Sep 27 2012 14:00:23 +03:00

No matter what I do, the value is sent as null to the controller. I get this error on the username in the controller:
 
Value cannot be null.
Parameter name: username
 
view:

@Html.EditorFor(model => model.User.UserName)
@Html.ValidationMessageFor(model => model.User.UserName)
 
model:
[Required]
[Display(Name = "User name")]
[Remote("doesUserNameExist", "UserServiceProvider", HttpMethod = "POST", ErrorMessage = "User name already exists. Please enter a different user name.")]
public string UserName { get; set; }

Controller:
public JsonResult doesUserNameExist(string UserName)
 {
var user = Membership.GetUser(UserName);
return Json(user == null);
}

Naomi
by Naomi on Friday, Dec 28 2012 03:02:29 +02:00

I got the same error as the above poster - the value was sent as null. I changed the above to be model.UserName (e.g. don't use complex property as properties of another object) and then validations worked fine.

However, I am also facing another issue - in my case validations fire on each new character I type instead of firing after I leave the field. I am not sure what is causing this behavior - I am using modal jquery dialogs - could it be the problem?

kashyap
by kashyap on Monday, Jun 17 2013 12:05:35 +03:00

Excellent!!!! It works well!!!!!

Jason Presley
by Jason Presley on Wednesday, Jul 10 2013 00:32:40 +03:00

Does the The Remote validator work in MVC 4?  I have seen this described in several blog posts but I'm trying it and I get nothing.  Either I'm missing something that all of the posts are assuming or there is something broken in MVC 4.  Any help of suggestions would be appreciated.  Thanks!

shekhar
by shekhar on Friday, Jul 12 2013 10:23:04 +03:00

I have implemented this using MVC4 but not displaying error message. it is hitting verify method on controller and controller also returning the error message but not displaying on the page. i might be doing some thing wrong. any help would be appreciated.

aLeX
by aLeX on Thursday, Dec 05 2013 15:09:45 +02:00

Awesome!

Don't forget to allow anonymous call if needed !

[AllowAnonymous]

Yecid
by Yecid on Thursday, Feb 27 2014 20:13:47 +00:00
Excellent!!!! Thank you!!! It works perfect!!!!!
ecaps24
by ecaps24 on Tuesday, Mar 04 2014 03:32:10 +00:00
It definitely works on Create View but you have to disable this validation in Edit View. How can you do that?
badharudeennajimudeen
by badharudeennajimudeen on Monday, Mar 24 2014 07:41:02 +00:00
very nice...
Joe
by Joe on Tuesday, Apr 15 2014 14:45:42 +00:00
I have used this line in RegisterModel: [System.Web.Mvc.Remote("doesUserNameExist", "Account", HttpMethod = "POST", ErrorMessage = "User name already exists. Please enter a different user name.")] After clicking on "Register" button, nothing is happening. How to solve this problem?

New Comment