Click here to Skip to main content
15,868,016 members
Articles / Web Development / ASP.NET

Creating a custom user login form with .NET C# MVC 4 Razor

Rate me:
Please Sign up or sign in to vote.
4.70/5 (90 votes)
23 Oct 2012CPOL4 min read 770.3K   29.5K   100   66
Article about creating a custom login form with MVC4, C# and Razor

Introduction 

Majority of web projects needs handling users and therefore user login section.  In this article I'm writing about how quickly create user login, logout functionality and display that status.

This article is not related to any specific database so you can use whatever you need, e.g. MSSQL, PostgreSQL, MySQL etc... In this case I'm showing example with MSSQL. 

Steps to reach the goal 

Step 1. Creating a project. 

In those screenshots I'm creating MVC4 project, but this tutorial should work on MVC3 too.

Image 1

Then select that you are using Razor engine. Check create Tests if you are planning to use it later in your project. If not - leave it unchecked.

Image 2

Step 2. Creating a database

Right click on App_Data -> Add -> New item... ->Data -> SQL Server Database -> OK.

Now we need a users table.

Right click on Tables and open New Query window.

Image 3

Now paste code below to that query window and click execute (shortcut CTRL+SHIFT+E)

SQL
CREATE TABLE [dbo].[System_Users]
(
	[Id] INT NOT NULL IDENTITY ,
	[Username] NVARCHAR(50) NOT NULL,
	[Password] NVARCHAR(MAX) NOT NULL,
	[RegDate] DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
	[Email] NVARCHAR(50) NOT NULL,
	PRIMARY KEY ([Id])
)
GO
CREATE INDEX [IX_System_Users_Username] ON [dbo].[System_Users] ([Username])
GO
INSERT INTO [dbo].[System_Users]
	([Username], [Password], [Email])
VALUES
	('test', 'a94a8fe5ccb19ba61c4c0873d391e987982fbbd3', 'test@test.test')
GO

This code has created a table and inserted user test with password test. Password is encoded with SHA1. To generate your own - google online converter to sha1, but in this example better leave it as it is.

Step 3. Creating a HomeController 

OK. Now we need a home controller which will be our first page.

Image 4

Image 5

Step 4. Creating a Home view.

Right click on method name -> Create view.

Image 6

Call it Index (The same as method name) and select to use layout.

Image 7

Step 5. Creating a User model

User model is required to handle user information and for form creation.

Right click on Models -> Add -> New item... -> Code -> Class; Name it User.cs.

In User class code should look like this:

C#
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
 
namespace Creating_a_custom_user_login_form.Models
{
    public class User
    {
        [Required]
        [Display(Name = "User name")]
        public string UserName { get; set; }
 
        [Required]
        [DataType(DataType.Password)]
        [Display(Name = "Password")]
        public string Password { get; set; }
 
        [Display(Name = "Remember on this computer")]
        public bool RememberMe { get; set; }
        
        /// <summary>
        /// Checks if user with given password exists in the database
        /// </summary>
        /// <param name="_username">User name</param>
        /// <param name="_password">User password</param>
        /// <returns>True if user exist and password is correct</returns>
        public bool IsValid(string _username, string _password)
        {
            using (var cn = new SqlConnection(@"Data Source=(LocalDB)\v11.0;AttachDbFilename" + 
              @"='C:\Tutorials\1 - Creating a custom user login form\Creating " + 
              @"a custom user login form\App_Data\Database1.mdf';Integrated Security=True")) 
            {
                string _sql = @"SELECT [Username] FROM [dbo].[System_Users] " + 
                       @"WHERE [Username] = @u AND [Password] = @p";
                var cmd = new SqlCommand(_sql, cn);
                cmd.Parameters
                    .Add(new SqlParameter("@u", SqlDbType.NVarChar))
                    .Value = _username;
                cmd.Parameters
                    .Add(new SqlParameter("@p", SqlDbType.NVarChar))
                    .Value = Helpers.SHA1.Encode(_password);
                cn.Open();
                var reader = cmd.ExecuteReader();
                if (reader.HasRows)
                {
                    reader.Dispose();
                    cmd.Dispose();
                    return true;
                }
                else
                {
                    reader.Dispose();
                    cmd.Dispose();
                    return false;
                }
            }
        }
    }
}

It could be necessary to modify a connection string on your computer.

var cn = new SqlConnection(@"Data Source=(LocalDB)\v11.0;AttachDbFilename='C:\Tutorials\1 - Creating a custom user login form\Creating a custom user login form\App_Data\Database1.mdf';Integrated Security=True") 

It can be found here: 

Image 8

NOTE: connection string must be placed in web.config!

Step 6. Creating additional helpers

As you may noted Helpers.SHA1.Encode(_password); is underlined in red. It's because there's no such class and method yet.

Now we are going to add additional shared project to our solution and create our Helper.

In solution Explorer right click on Solution then Add -> New Project... -> Windows -> Class Library; Name it Helpers.

In Solution Explorer right click on Helpers project and Add -> New item... -> Code -> Class; Name it SHA1

Code int his class must should look like this:

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace Helpers
{
    public class SHA1
    {
        public static string Encode(string value)
        {
            var hash = System.Security.Cryptography.SHA1.Create();
            var encoder = new System.Text.ASCIIEncoding();
            var combined = encoder.GetBytes(value ?? "");
            return BitConverter.ToString(hash.ComputeHash(combined)).ToLower().Replace("-", "");
        }
    }
}

Now we need to reference it to our main project. Right click on our website project then Add Reference... -> Select Helpers (checkbox) and hit OK.

Step 7. Creating User Controller  

We need a user controller to manage user who's about to log in or log out. Create controller as you did previous and name it UserController. I preffer naming it User (not Users) becouse it stands for ONE user.

This is code which should appear in it.

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
 
namespace Creating_a_custom_user_login_form.Controllers
{
    public class UserController : Controller
    {
        //
        // GET: /User/
        public ActionResult Index()
        {
            return View();
        }
 
        [HttpGet]
        public ActionResult Login()
        {
            return View();
        }
 
        [HttpPost]
        public ActionResult Login(Models.User user)
        {
            if (ModelState.IsValid)
            {
                if (user.IsValid(user.UserName, user.Password))
                {
                    FormsAuthentication.SetAuthCookie(user.UserName, user.RememberMe);
                    return RedirectToAction("Index", "Home");
                }
                else
                {
                    ModelState.AddModelError("", "Login data is incorrect!");
                }
            }
            return View(user);
        }
        public ActionResult Logout()
        {
            FormsAuthentication.SignOut();
            return RedirectToAction("Index", "Home");
        }
    }
}

Step 8. Creating a login view 

Right click on Login method name and create view.

Image 9

Use layout template as previously.

Step 9. Making login form

Code should look like this:

ASP.NET
@model Creating_a_custom_user_login_form.Models.User
@{
    ViewBag.Title = "Login";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
@using (Html.BeginForm())
{
    @Html.ValidationSummary(true, "Login failed. Check your login details.");
    <div>
        <fieldset>
            <legend>Login</legend>
            <div class="editor-label">
                @Html.LabelFor(u => u.UserName)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(u => u.UserName)
                @Html.ValidationMessageFor(u => u.UserName)
            </div>
            <div class="editor-label">
                @Html.LabelFor(u => u.Password)
            </div>
            <div class="editor-field">
                @Html.PasswordFor(u => u.Password)
                @Html.ValidationMessageFor(u => u.Password)
            </div>
            <div class="editor-label">
                @Html.CheckBoxFor(u => u.RememberMe)
                @Html.LabelFor(u => u.RememberMe)
            </div>
            <input type="submit" value="Log In" />
        </fieldset>
    </div>
}

Here we create our form, add labels and validators.

Step 10. Editing _Layout.cshtml page (add login button)

This file is in Views -> Shared folder.

We are going to add this code so it will allow us to login, log out and displays our name.

ASP.NET
<div style="width: auto; background-color: #728ea7;">
    @if (Request.IsAuthenticated) {
        <strong>@Html.Encode(User.Identity.Name)</strong>
        @Html.ActionLink("Sign Out", "Logout", "User")
    }
    else {
        @Html.ActionLink("Register", "Register", "User")
        <span> | </span>
        @Html.ActionLink("Sign In", "Login", "User")
    }
</div> 

It checks (Request.IsAuthenticated) if user is logged in and then displays its name. Also it displays Register button, but in this article I'm not going further with it.

The whole _Layout.cshtml code should look something like this:

ASP.NET
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")
</head>
<body>
    <div style="width: auto; background-color: #728ea7;">
        @if (Request.IsAuthenticated) {
            <strong>@Html.Encode(User.Identity.Name)</strong>
            @Html.ActionLink("Sign Out", "Logout", "User")
        }
        else {
            @Html.ActionLink("Register", "Register", "User")
            <span> | </span>
            @Html.ActionLink("Sign In", "Login", "User")
        }
    </div>
 
    @RenderBody()
 
    @Scripts.Render("~/bundles/jquery")
    @RenderSection("scripts", required: false)
</body>
</html>

Thats it!

The source code can be downloaded here.

Review 

So what we have did here. We created a table with test user. Data is hashed, so we can call it kind of secure. We have included external project with helper functions. It can be filled with more useful stuff and shared with other your projects in the same way you did here. (I like to seperate Interfaces and Business logic like this too).

Next we build two controllers and views. One for first page and other for user login.

We have edited our Layout so we could see some information and login buttons all the time (while we are using that layout)

I hope this article helped you to understand basic usage and will help you in future.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Lithuania Lithuania
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Questionsolution Pin
VipinLakhe12-Sep-16 23:19
VipinLakhe12-Sep-16 23:19 
Questionerror Pin
VipinLakhe12-Sep-16 22:38
VipinLakhe12-Sep-16 22:38 
QuestionExcellent walkthrough for newbies! Pin
Douglas Acosta27-Jul-16 4:01
Douglas Acosta27-Jul-16 4:01 
QuestionParser Error Pin
Member 1112581325-Apr-16 21:30
Member 1112581325-Apr-16 21:30 
QuestionSHA1 & Metadata file Pin
Member 99829379-Mar-16 1:30
Member 99829379-Mar-16 1:30 
QuestionSHA1 Problem Pin
Member 111256383-Mar-16 23:02
Member 111256383-Mar-16 23:02 
QuestionLogin page in asp.net Mvc4 Web application Pin
Member 1219032018-Dec-15 20:28
Member 1219032018-Dec-15 20:28 
BugUnable to extract source code Pin
Member 119735368-Nov-15 19:12
Member 119735368-Nov-15 19:12 
QuestionNice Pin
Member 1108389527-Oct-15 2:01
Member 1108389527-Oct-15 2:01 
QuestionU. Pin
Member 1199914020-Sep-15 20:42
Member 1199914020-Sep-15 20:42 
BugExtracting from the source code Pin
Yogesh Sindwani18-Jun-15 1:41
Yogesh Sindwani18-Jun-15 1:41 
SuggestionProblem solved Pin
Maurizio Felicella4-May-15 5:55
Maurizio Felicella4-May-15 5:55 
QuestionNice One Pin
Yessoufou Abdel22-Apr-15 1:34
Yessoufou Abdel22-Apr-15 1:34 
Questiongetting a error Pin
atuk230810-Apr-15 5:31
atuk230810-Apr-15 5:31 
QuestionThanks Pin
Andan HM22-Mar-15 20:27
professionalAndan HM22-Mar-15 20:27 
Questionhow can we add Edit page? Pin
Ahmet Sen8-Feb-15 13:22
Ahmet Sen8-Feb-15 13:22 
QuestionThanks. Pin
zamkinos26-Dec-14 9:46
zamkinos26-Dec-14 9:46 
Questionhow can i prevent user to access other controllers/views if he is not logged in? Pin
Tal Rahav18-Nov-14 22:28
Tal Rahav18-Nov-14 22:28 
Questioncould login with saved plain text Pin
Shreetam Mishra7-Nov-14 0:00
Shreetam Mishra7-Nov-14 0:00 
QuestionThanks sir Pin
ashu_om5-Nov-14 9:31
ashu_om5-Nov-14 9:31 
Generalweb.config Pin
JoshYates198021-Oct-14 8:58
professionalJoshYates198021-Oct-14 8:58 
QuestionHow to pass encrypted data from view to controller Pin
Surendraz10-Oct-14 21:43
Surendraz10-Oct-14 21:43 
QuestionGood, Pin
silvagpe18-Aug-14 3:23
silvagpe18-Aug-14 3:23 
GeneralMessage Closed Pin
25-Jun-14 0:37
Binu198525-Jun-14 0:37 
QuestionAdd Register Functions to the Project Pin
ilksan30-Mar-14 22:17
ilksan30-Mar-14 22:17 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.