Making a registration system with Asp.Net and Linq-to-SQL (part 1)

This registration has a slick interface and user verification

NOTE* I do not cover encryption in this tutorial, but I highly discourage storing plain-text passwords in your DB!

It is inevitable that every programmer will want to eventually make a site which requires registration. Then you need to deal with spam accounts and all that good stuff. This is part one of a series of tutorials, where I will show you how to set up a registration process that requires a valid email address. I will be building on the code provided here for the next tutorial and so on. In the future, I will also include a login process I developed that will lock out accounts after a certain amount of attempts, retrieve passwords, and all sorts of other goodies. But before users can log in, they have to register.

I will be using a lot of other people's stuff in this example, such as jQuery, jQuery extensions, Grid960 and so on as well as a lot of my own Extensions, etc. With that said, this is going to have a lot of 'extras' included such as Ajax functionality and some UI niceties to make it a quality interface - you can feel free to cut these parts out, but I feel it will be nice for those that want it. All of the code referenced is included.


The first step is setting up your user table in the database. The most important thing to think of here is: what am I going to need to collect? I am all about being as simple as possible, so I am going to require two things: email and password - that is it. This is what I came up with:
  • userid - the primary key integer
  • email - the user's email
  • password - user's password
  • guid - guid for verification
  • created - date created; both for record keeping and to see if it was not confirmed after a long time it can be removed
  • confirmed - whether or not it is confirmed
  • last try* - the last login
  • number of failed logins* - number of failures for lockout

The two starred items will not really be used in this too tutorial and are optional if you do not want to prevent unlimited login attempts; though they will be relevant in upcoming tutorials.

Here is the SQL to create my table for users:
CREATE TABLE dbo.users (
password_ VARCHAR(30) NOT NULL,


Now that we have our table, go ahead and drag it into a dbml - for this example, I will use one named db.dbml. Now we have our access layer built, we can work on making a registration control; I will be making an ascx registration control, so it can be plugged in aywhere I want to use it. Since I am only collecting two bits of information, this will be a simple control. Here is the markup, I will explain it afterwards:

<asp:UpdatePanel ID="upContact" runat="server">
    <div class="pad">
      <asp:Panel ID="Report runat="server" />
      <asp:Panel ID="pnlRegister" runat="server" DefaultButton="registerSubmit">
        <div class="pad_sides">
              <asp:RequiredFieldValidator ID="rfvRegisterEmail" runat="server" CssClass="validate" ValidationGroup="register"
                ControlToValidate="registerEmail" ErrorMessage="required" Display="Dynamic" />
            <asp:RegularExpressionValidator ID="regRegisterEmail" runat="server" ControlToValidate="registerEmail"
                ErrorMessage="invalid email" CssClass="validate" Display="Dynamic" ValidationGroup="register"
            <asp:TextBox ID="registerEmail" runat="server" CssClass="inputBig full" />
            <asp:RequiredFieldValidator ID="rfvRegisterPassword" runat="server" CssClass="validate" ValidationGroup="register"
                ControlToValidate="registerPassword" ErrorMessage="required" Display="Dynamic" InitialValue="8 character minimum" />
            <asp:RegularExpressionValidator ID="regRegisterPassword" runat="server" CssClass="validate" ValidationGroup="register"
              ControlToValidate="registerPassword" ErrorMessage="must be at least 8 characters" Display="Dynamic"
              ValidationExpression="^.{8}.*$" />
          <asp:TextBox ID="registerPassword" runat="server" CssClass="inputBig full wm watermark" Text="8 character minimum" />
        <div class="summary field">
          <asp:LinkButton ID="registerSubmit" CssClass="button"
            Text="submit" runat="server" ValidationGroup="register" onclick="registerSubmit_Click" />

Ok, there is a lot going on here, so I will go part by part.

First of all, you will notice that it is within a Asp.Net UpdatePanel which I have been trying to get away from for most things, but for such small controls I have found that is is the best way to go about it: easy and fast.

Next you will see that I have added a Panel with an ID of "Report" - I use this as a standard in most applications as to where to output my 'updates' to the user. This is explained here. The code for this is included in the Extensions.cs file.

Next there is a good amount of validation going on.
  • First I use RequiredFieldValidators for both fields
  • Then I added the RegularExpressionValidator for emails
  • Then I added the RegularExpressionValidator for password length
  • Finally you will notice that the password entry has a watermark which is called via jQuery in the MasterPage

You might notice that I am not using a password field or asking for password verification. This is something you might want to do, but for this example, security is not really a concern, simplicity is; so I figure if you can see your password, you wont screw it up. Also, since we will be adding a password retrieval function, this won't be a big deal.


That is the markup, but now we have to go to the code so it actually does something. Now what does this have to accomplish?
  • Check if the Email has already been registered
  • Create a new entry in the users table
  • Send an email with a verification link

Not too much going on here, here is the code for accomplishing that, followed by an explanation:

using System;

public partial class controls_register : System.Web.UI.UserControl
  protected void Page_Load(object sender, EventArgs e)
    if (this.Attributes["in_page"] != null)

  protected void registerSubmit_Click(object sender, EventArgs e)
      dbDataContext db = new dbDataContext();
      if(Users.DuplicateEmail(db, registerEmail.Text))
        throw new Exception("email already registered");
      Guid g = Guid.NewGuid();
      user u = new user()
        created = DateTime.Now,
        email = registerEmail.Text,
        guid_ = g,
        password_ = registerPassword.Text,
      Email email = new Email(registerEmail.Text, Settings.Get("gm"),
        "please verify your email address",
        "" + g.ToString()); //we will get to this in the next tutorial
      Report.Success("account successfully created", "please check your email to verify your account");
      pnlRegister.Visible = false;
      catch (Exception ex)

The first thing that happens here is the check for if the Attribute "in_page" is set. This is a bit of a sidebar as it just takes care of duplicate validators if there is more than one of these controls on the page, since I plan on showing how to use them both as a modal popup as well as a standalone page I had to add this check; that way, if you are filling out the popup instead of the form on the page it makes sure that it will not fire the validation for the form you are not using, all it does is change the validation group. The code is visible in the Utils class if you are curious about it. Don't really worry about this too much right now, as it will be covered in an upcoming tutorial.

Next it checks if the email is a duplicate. This calls the Users.cs class, we will get to that next; just remember for now it returns true if it is already in the system, false if not.

If it is new, a new user is then made and inserted into the DB via Linq-to-SQL.

An email is made and sent to the user with the link to the authorization page (which will be coevered in the next tutorial). This is sent using a simplified Email class. The authorization is the guid which was produced - I will cover the authorization page in the next part of the tutorial.

Then the user is notified of the status whether it is success or error using the panel reporting extensions.

This is all pretty simple, all that is left is to explain what is going on in the Users.cs class which is also simple:

using System.Linq;

public static class Users
  public static user GetFromEmail(dbDataContext db, string email)
  { return db.users.First(u =>; }

  public static bool DuplicateEmail(dbDataContext db, string email)
      user temp = GetFromEmail(db, email);
      span class="var">return true;
    catch { return false; }

As you can see, this is just two basic LINQ queries, the first one retrieving a user object based on an email string. And the duplicate check which tries to find a user with the given email, if it can, it will return true, meaning it is already in there, otherwise it spits out a false.

And that is all there is to it so far. It is not yet a working system as the user has not verified their identity, but we have accomplished the base of a registration system:
  • Collected the user's email address
  • Collected their password
  • Produced a unique Guid for verification
  • Sent them an email to verify their identity

Now we have it all built, we just need to display everything and call the necessary scripts. I am going to stick all of these pages within a masterpage which calls the scripts in the Page_Load:

protected void Page_Load(object sender, EventArgs e)
  Page.ClientScript.RegisterClientScriptInclude(typeof(demo), "jQuery", ResolveUrl("~/js/jquery.js"));
  //this will be used in the next tutorial
  Page.ClientScript.RegisterClientScriptInclude(typeof(demo), "jQuery", ResolveUrl("~/js/jqModal.js"));

Then just call the control (registered in the web.config file) and the js in the markup:

<cc:register id="reg" runat="server" />

and call the watermark frorm jQuery:

<script type="text/javascript" language="javascript">
   $().ready(function() {
     swapValues = [];
     $(".wm").each(function(i) {
       swapValues[i] = $(this).val();
       $(this).focus(function() {
         if ($(this).val() == swapValues[i]) {

Notice that I am calling the watermark in the masterpage. This may seem strange, but this stops me from writing redundant code as this will take care of *all* watermarks that I will put into this project due to the versatiliy of jQuery.

All we have to do to complete this registration process is to verify the email which will be the next part to this tutorial. I am also going to show how to add this into a registration popup. The hard part is all finished.

Shout it » Part 2 » Part 3

Using jquery.autosuggest.js with Asp.Net

Simple Auto-Suggest with Asp.Net and jQuery

After getting fed up with the Ajax Control Toolkit's AutoCompleteExtender and it's inability to deal with strings that are numbers, I decided to look to my new friend jQuery. Apparently they decided for you if you are feeding it an array of number strings (i.e. { "001","002", etc.}) that the auto-suggest will strip all leading zeroes... BUT I NEEDED THOSE ZEROES!

The jQuery solution is pretty simple, much easier than I thought thanks to this awesome plugin: jquery.autocomplete.js. All you really need to do is make a simple aspx page that spits out the data you want based on a QueryString, use a little jquery to tie it up with a TextBox and you are all set. Here is how its done:

Make your data retrieval page

This plugin consumes it's data in one form: text, with one item per line. This makes it very easy to use and very versatile. You could simply point it at a static .txt file, feel it a javascript variable, or, what we are going to do, use Asp.Net to get you some filtered data.

This tutorial is going to use two examples, one pulling from a list of numbers 1-1000, and another pulling form an xml file.

First, the code-behind for number.aspx:
protected void Page_Load(object sender, EventArgs e)
  if (!string.IsNullOrEmpty(Request.QueryString["q"]))
    int q = 0;
    if (Int32.TryParse(Request.QueryString["q"], out q))
      for (int i = q; i < 1001; i++)
        if (i.ToString().Contains(q.ToString())) Response.Write(i + Environment.NewLine);
      Response.Write("Not a number fool!");

Doesn't get much easier than that... simply writes out any numbers that contain the number (not mathematically, though we could do that) passed in the 'q' QueryString, so if you were to pass the url: number.aspx?q=100 you will get the results:


Now we do the same thing, but dig into an xml file with Linq:
protected void Page_Load(object sender, EventArgs e)
  string q = Request.QueryString["q"] ?? string.Empty;
  IEnumerable<string> things = from p in XDocumentLoad(path).Descendants("thing")
        where p.Value.Contains(q) select p.Value;
  foreach(string s in things) Response.Write(s + Environment.NewLine);

That was actually the hardest part. Notice that on the Response.Write() I used Environment.NewLine - that will make a newline in the proper format for the jquery to digest, a <br /> or a \n will not work with this plugin. What was made is a psuedo-web-service (it's not really becuase it does not output xml).

Tie it to some TextBoxes

Now just make a couple TextBoxes that will use them:
<asp:textbox ID="txtNumbers" runat="server" />
<asp:textbox ID="txtThings" runat="server" />

Now use jQuery to attach the pages we made to the proper TextBox:

$().ready(function() {

And that's it, you have working auto-suggesters; pretty simple. One thing to notice that can give you some headaches in Asp.Net is that I used the IDs for selection in the code, which is fine if you are not using User Controls or Masterpages, but if you are you get those funky '...ctl100_...' ids that are made at runtime, so you might want to select them with a different method, like making a dummy class and using that as a selector in jQuery

That's about it - but don't forget to style your auto-suggest box or it will just be transparent; there is some basic css showing the classes produced by the jquery in the example. This was just enough to get you started; there is a bunch of documentation and other variables, settings, formatting tricks that you can use (this is a really powerful plugin) - you can read up on them here:

IMPORTANT: Remember to delete *everything* on your handling .aspx page other than the '@' declaration so you don't have any extra html in there (I think I left it in there on the download...).

jQuery TextBox Water Mark with

A jQuery alternative to the AjaxControlToolkit TextBoxWaterMarkExtender

I stole majority of this code from but I added a bit to make it swap css classes as well

$().ready(function() {
  swapValues = [];
  $(".wm").each(function(i) {
    swapValues[i] = $(this).val();
    $(this).focus(function() {
      if ($(this).val() == swapValues[i]) {
    }).blur(function() {
        if ($.trim($(this).val()) == "") { $(this).val(swapValues[i]).addClass("watermark") } }) })

To use it, make sure your TextBox has (one of) it's css classes set to "wm". If you want a seperate style to be applied add that initially as well, in my example, it swaps "watermark" in and out as a css class.

<asp:TextBox ID="txt" runat="server"
  Text="this is the watermark" CssClass="wm watermark" />

Cascading DropDowns using XML and LINQ

A simple alternative method to the Ajax Control Toolkit's

Don't get me wrong, the Ajax Control Toolkit (ACT) is great, but a couple of the controls leave something to be desired.  For one, the things required to integrate the cascading dropdowns is a bit excessive IMO.  No need ot require asmx files to do a simple lookup.  Also, if you are changing values in your dropdowns (as I needed to do), this gives you no simple way to do it.


Figuring that dropdowns are almost always relatively small collections of choices, and I would be editing them often for my purposes, an XML files seems to be the perfect fit for this situation.  On top of that, with the ease of LINQ, this would be extremely easy to make an interface for editing the properties so my users could edit them without knowing the first thing about XML. 


I am going to try to basically copy the ACT in terms of functionality as I really like it, but change it 'under the hood'.  First thing is to make a simple XML file with my options in it, I used old cars for an example:

<?xml version="1.0" encoding="utf-8" ?>
        <maker>-please select-</maker>
        <car_maker name="Ford">
        <car_maker name="Chevy">
        <car_maker name="Dodge">

 Now add the Dropdowns to yoru .aspx with a few more properies added (required for this to work) the properties are:

  1. cascadeTo : The dropDown you want to cascade to
  2. cascadeCategory : The category in XML your cascade properties lie
  3. cascadeDescendant : The final level in XML where your items lie
  4. cascadeBlank : [optional] What the cascading DropDown will display when it is awaiting a selection

Here is my .aspx, Notice I added "- Select Make -" to the ddlModel DropDownList as that will help give the user some guidance and it is the same as the 'cascadeBlank' I designated:

Make:<br />
<asp:DropDownList ID="ddlMake"  runat="server" cascadeTo="ddlModel" cascadeCategory="car_maker" cascadeDescendant="car" cascadeBlank="- Select Make -"  AutoPostBack="true" onselectedindexchanged="ddlMake_SelectedIndexChanged" />
<br /><br />
Model:<br />
<asp:DropDownList ID="ddlModel" runat="server" Enabled="false"  >
    <asp:ListItem>- Select Make -</asp:ListItem>

Next, you need to access your XML document and fill your initial menu, so make sure to add something like this to your code-behind:

XElement x;
protected void Page_Load(object sender, EventArgs e)
    x = XElement.Load(Server.MapPath(".") + "\\App_Data\\dropdowns.xml");
    if (!IsPostBack)
        foreach (XElement elem in x.Descendants("maker")) addDdlItems(ddlMake, elem.Value);

public void addDdlItems(DropDownList ddl, string value)
    ListItem li = new ListItem();
    li.Value = value;

Now you simply need to call cascade.fromThisDropDown from your _SelectedIndexChange event.  This way you don't need to write any code, just place the cascade.cs fil into your App_Code folder:

protected void ddlMake_SelectedIndexChanged(object sender, EventArgs e)
 { cascade.fromThisDropDown(this.Page, (DropDownList)sender, x); }

And that's it.  You can place it inside an UpdatePanel for the same exact Ajax effect that you have with the ACT, but without those pesky asmx files. If you want to see the cascade.cs code, click here to view/hide.


Not completely dummy proof, but I think it's useful.  You can download just the cascade class, or the full working example:



You know all those slick loading images you see all over the internet? Ever borrow one from a different site and the colors or the look just weren't right? This site makes custom loading images and is completely free - a slick resource