Check Duplicate User Names In ASP.NET Web Pages Sites

5 (3 votes)

The Web Pages Starter Site template provides a useful starting point for developing a Razor Web Pages site that includes membership. But it doesn't include any mechanism for preventing duplicate user names. This article offers one solution to the problem that uses jQuery.

If you ask how to prevent duplicate user names in forums, one of the suggestions that is often put forward is to apply a unique constraint in the database column that holds the user name. Any attempt to submit a duplicate value will result in an exception being raised in the relevant database provider. You can catch this exception and show the user an appropriate message. This works - and you are always advised to add unique constraints to database columns that should hold unique values - but it's a fairly clunky solution. And many people feel that you should not use exceptions as a means to manage your business rules (myself included).

The solution featured in this article uses AJAX to query the database and to give the user immediate feedback when they enter their chosen user name. The AJAX call requests a page that exists purely to query the database to see if the selected user name is already in use. The solution also includes a server side chekc to ensure that users who have disabled JavaScript so not slip through the net. The solution requires a couple of amendments to the Register.cshtml file in the Starter Site, and the addition of 3 files. But first, the changes to the Register.cshtml page. The first change is in the inclusion of a JavaScript file called dupecheck.js (which will be created a bit later):

@* Remove this section if you are using bundling *@
@section Scripts {
    <script src="~/Scripts/jquery.validate.min.js"></script>
    <script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
    <script src="~/Scripts/dupecheck.js"></script>

And the second is the server side check to see if the username is in use:

    ModelState.AddError("email", "User name is already taken");

I placed this in the if(IsPost) section just after the initial variables that represent the submitted values (email, password and confirmPassword) are declared. The code calls a function named IsDuplicate. The function is declared in a file called Functions.cshtml which is placed in a folder called App_Code:

@functions {
    public static bool IsDuplicate(string username){
        var db = Database.Open("StarterSite");
        var commandText = @"SELECT COUNT(Email) FROM UserProfile WHERE Email = @0";
        return (int)db.QueryValue(commandText, username) > 0;
Note that the name of the folder is important. The function returns a bool. The value of the bool is determined as a result if the SQL query which gets a count of the rows containing the provided user name. By default, the Starter Site uses a column called Email in the UserProfile table for the storage of user names. This function is also called in a separate file named DupeCheck.cshtml. This file is placed in the root of the site:


    Layout = null;
        var username = Request["username"];
        var result = Functions.IsDuplicate(username);
        Json.Write(new { isDupe = result }, Response.Output);

DupeCheck.cshtml is designed to work exclusively with AJAX. The code includes an instruction to nullify any layout pages that might have been set in a _PageStart file, and then it uses the IsAjax property to determine if the page has been requested via an AJAX call. If it has, it uses the IsDuplicate method to check the availability of the posted username and returns the result to the calling code. The result is an anonymous type that has one propery: isDupe, which is a boolean. The anonymous type is serialised to JSON by the Json helper.

The final part of the solution is the dupecheck.js file. This uses jQuery:

$(function () {
    $('#email').change(function () {
            { username: $(this).val() },
            function (data) {
                var emailValidation = $('span[data-valmsg-for="email"]');
                if (data.isDupe) {
                    if (emailValidation.hasClass('field-validation-valid')) {
                        emailValidation.text('That name is already taken!');
                } else {
                    if (emailValidation.hasClass('field-validation-error')) {

An event handler is attached to the change event of the user name input (which has an id if email in the Starter Site). The current value is posted to the DupeCheck.cshtml page via AJAX. The code above checks the response from the server to see if the value is a duplicate, and if it is, an appropriate error message is displayed to the user.

And there it is - a clean way to provide users with immediate feedback on the availability of their chosen user name.


Date Posted:
Last Updated:
Posted by:
Total Views to date: 24594


- Fish

Why do the "IsAjax" check?
This somehow related to security? And if how how does it become more secure?

- Mike


As it says in the article, the IsAjax property returns true if the request was made by AJAX. That means that people can't simply put in their browser and request the file. Also, by default, cross origin AJAX requests are not allowed, so it acts as protection against misuse.

- satyabrata

Nice post.very helpful.

- Kelvin

But isn't dere a way to check if the user's exist without posting d form . becos u can actually if a user exists server side without using ajax .wanted a client side script to achieve this

- Mike


I have no idea what you are asking. Did your cat walk across the keyboard as you were typing?

- Gautam

Thank you for this post Mike!

But ii have a doubt reg starter site, u said it doesn't check for duplicate user name. But I checked it does. Before adding the user, it queries the database to chk for user(email) ..
If user == null, then only it proceeds otherwise it says "user exists'

- Mike


As far as I can remember, the first version of the site didn't, but the current one does.

- Gautam

Hi Mike,

In the below line

return (int)db.QueryValue(commandText, username) > 0;

why the (int)... is it type casting? if yes, the why is it required. I removed it and tested, query returns an interger only

- Mike


In this case the cast probably isn't necessary, but Database.QueryValue returns a dynamic type, not an integer. The runtime binder is responsible for choosing an appropriate type.

Recent Comments

Rajasekar 24/11/2015 12:27
In response to Import Data From Excel to Access with ASP.NET
While use this code i'm facing on error: "Unrecognized Database format C:\mydabase.accdb" can any...

Parmod 24/11/2015 07:28
In response to ASP.NET 5 Project Basics
For a new learner (Fresher) in ASP.NET there is a issue Fresher have to learn two types of , old...

Robert 22/11/2015 21:35
In response to ASP.NET 5 By Numbers
I have to agree fully with Paul, this does sound like an entire mis-mash of technologies. Sort of in...

Christian 21/11/2015 15:46
In response to MVC 5 with EF 6 in Visual Basic - Creating an Entity Framework Data Model
Many thanks Mike to introduce me in the EF6 Code First way of thinking. Exactly what I need for my...

ax plains 20/11/2015 16:29
In response to Examining the Details and Delete Methods
Hello, really great tutorial for a beginner like me! Is it possible to have an explanation on how a...

Abdul Latif 20/11/2015 14:42
In response to Reading Excel Files Without Saving To Disk In ASP.NET
Could anyone please help me, I am getting : "OfficeOpenXml.ExcelPackage" does not contain a for...

Thomas 20/11/2015 09:44
In response to Cheat Sheet - .NET Framework Exceptions
Hey Mike, nice list. I've also checked your article on how you created the list, but is there any to...

Pramod Gagare 19/11/2015 11:18
In response to Date Formatting in C#

Robby 19/11/2015 08:16
In response to WebMatrix - Database Helpers for IN Clauses
Would it also be possible to override the default query and querysingle methods to include the azure...

Menja 18/11/2015 08:28
In response to Sessions and Shopping Carts
Thank you for a perfect description and that you show all the screenshot at the same time!!! It a...