Click here to Skip to main content
Click here to Skip to main content

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

, 23 Oct 2012
Rate this:
Please Sign up or sign in to vote.
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.

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.

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.

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

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.

Step 4. Creating a Home view.

Right click on method name -> Create view.

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

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:

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: 

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:

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.

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.

Use layout template as previously.

Step 9. Making login form

Code should look like this:

@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.

<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:

<!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)

Share

About the Author

Vygandas Pliasas
Web Developer
Lithuania Lithuania
No Biography provided
Follow on   Google+

Comments and Discussions

 
QuestionGood, Pinmembersilvagpe18-Aug-14 3:23 
GeneralSimple Login From in MVC Using C#.Net PinmemberBinu198525-Jun-14 0:37 
QuestionAdd Register Functions to the Project Pinmemberilksan30-Mar-14 22:17 
Suggestionproblem while creating login.cshtml [modified] PinmemberAnwarSadat24-Mar-14 18:45 
QuestionThanks PinmemberMember 1066125111-Mar-14 3:55 
GeneralVery helpful Pinmembersafi rehman23-Feb-14 7:13 
QuestionSource code not unzipping PinmemberPritam Karmakar16-Feb-14 11:13 
AnswerRe: Source code not unzipping Pinmembergauravupadhyay14-Apr-14 21:49 
QuestionSource Code Not Unzipping PinmemberThe Kaushik Basu10-Feb-14 14:32 
AnswerRe: Source Code Not Unzipping Pinmembergauravupadhyay14-Apr-14 21:49 
QuestionХороший ман! PinmemberV01T2-Feb-14 21:07 
SuggestionAuthentication in Web.Config Must Be Enabled PinmemberMember 859973221-Jan-14 6:26 
SuggestionRe: Authentication in Web.Config Must Be Enabled PinmemberDonatas Stonys18-Mar-14 15:56 
QuestionFormsAuthentication Is Not Valid ??? PinmemberMember 1045709610-Dec-13 1:33 
AnswerRe: FormsAuthentication Is Not Valid ??? PinmemberMember 1052897316-Jan-14 9:45 
QuestionNot Working PinmemberMember 1011648012-Nov-13 2:09 
GeneralMy vote of 5 PinmemberJasonMacD29-Oct-13 4:09 
Questionthanks Pinmembermasoudhaghshenas2-Oct-13 22:32 
QuestionVery elegant. Very nice. Very much appreciated. PinmemberWilliam McGahan24-Sep-13 14:18 
GeneralMy vote of 4 PinmemberMember 102096209-Sep-13 11:27 
GeneralMy vote of 5 PinmemberMasoom Mir16-Aug-13 20:09 
QuestionNice article PinmemberMasoom Mir16-Aug-13 20:07 
GeneralGreat Article PinmemberAtif Khan15-Jul-13 0:30 
QuestionMy Vote is 4 PinmembervinodNagda9-Jul-13 19:30 
GeneralMy vote of 3 PinmemberMichael90008-Jul-13 9:11 

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

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

| Advertise | Privacy | Mobile
Web02 | 2.8.140827.1 | Last Updated 23 Oct 2012
Article Copyright 2012 by Vygandas Pliasas
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid