In this article, we will learn how to create custom login registration in ASP.NET MVC. If you are a newcomer and have just started learning the concept of ASP.NET MVC, then you have come to the right place. I have specifically written this article for newcomer developers and anyone who wants to create a custom login and registration form in ASP.NET MVC with a database connection without using Entity Framework.

After reading many articles on Google, I noticed that almost all articles are based on using Entity Framework. Therefore, in this article, I have decided to write a post on how to create custom login registration in ASP.NET MVC without Entity Framework.

Today in this article, I will explain the following points:

  1. How to create a Login and Registration page in MVC with a database.
  2. Registration and Login form in MVC with jQuery validation.

So let's start. First, we have to create a table for storing user information, such as name, email, and password, in the database.

SQL Script:

CREATE TABLE [dbo].[TblUsers](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](max) NULL,
    [Email] [nvarchar](max) NOT NULL,
    [Password] [nvarchar](max) NULL,
    [ContactNo] [nvarchar](max) NULL,
 CONSTRAINT [PK_TblUsers] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)
)

Key points in this article:

  1. Create an empty MVC application.
  2. Create a controller.
  3. Create a model.
  4. Create views depending on the controller.
  5. Create ActionResults for the actions.

What is MVC?

In simple language, if I say, this is a way in which we divide our database, logic, and visual Part. The full form of MVC is Model-View-Controller, which means that we have a known database as a model, and the logic part is known as the controller and the visual part is known as a view.

Talking about technical language, it is an architectural pattern with the help that we dividing a project into 3 components so that we can increase the security and productivity of the project. MVC is not about any special programming language because you can use it in any project whether it is in PHP, in ASP.NET, in Nodejs, in Python, you can use this architectural pattern method in everyone.

How does MVC work?

We have created an MVC diagram with the help of which one can easily know how MVC works. This diagram is different from another sample diagram but we will tell you the complete information about it.

User

Here the user can be any person who sends a specific URL or request to our project and wants a corresponding response or result of its specific URL or request.

Front controller

We can call this the main request and response system that takes a request from the user and sends its corresponding response back to the user.

Controller

When the process of request from the Front Controller is verified, then a specific controller is called which collects the data from the Model and the visual part from the view and sends the response back to the front controller.

View

In this, all the things are available that we have to send as a response to the user on a specific request.

Model

This is our data layer where we send the complete data of a database table or a specific data controller to a specific request and attach it to the view part.

Step 1-Open Visual Studio and create an Empty MVC Project

Step 2-Right-click on Controller folder and add two controllers in project i.e AccountController and HomeController.

Step 3-Right Click on Model for and add two classes i.e LoginViewModel and RegistrationViewModel and copy-paste the below code.

 

LoginViewModel.cs 

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace MvcDemoProject.Models
{
    public class LoginViewModel
    {
        [Required]
        [EmailAddress]
        [StringLength(150)]
        [Display(Name = "Email Address: ")]
        public string Email { get; set; }

        [Required]
        [DataType(DataType.Password)]
        [StringLength(150, MinimumLength = 6)]
        [Display(Name = "Password: ")]
        public string Password { get; set; }
    }
}

 

RegistrationViewModel.cs 

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace MvcDemoProject.Models
{
    public class RegistrationViewModel
    {
        public int Id { get; set; }

        [Required]
        [Display(Name = "Name: ")]
        public string Name { get; set; }

        [Required]
        [EmailAddress]
        [StringLength(150)]
        [Display(Name = "Email Address: ")]
        public string Email { get; set; }

        [Required(ErrorMessage = "You must provide a phone number,Phone Number at least 10 digit")]
        [Display(Name = "ContactNo")]
        [DataType(DataType.PhoneNumber)]
        [RegularExpression(@"^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$", ErrorMessage = "Not a valid phone number")]
        public string ContactNo { get; set; }

        [Required]
        [DataType(DataType.Password)]
        [StringLength(150, MinimumLength = 6)]
        [Display(Name = "Password: ")]
        public string Password { get; set; }
    }
}

Step 4-Now Let’s create an action method in both controllers , I have created one action method in HomeController and six Action Method in AccountController.

Copy the Below code in HomeController

HomeController

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcDemoProject.Controllers
{
    public class HomeController : Controller
    {
        // GET: Home
        public ActionResult Index()
        {
            return View();
        }
    }
}

When we will run the MVC project then by default this action will be called and return the Index View.

AccountController

using MvcDemoProject.Models;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;

namespace MvcDemoProject.Controllers
{

    public class AccountController : Controller
    {
        SqlConnection con = new SqlConnection("Data Source=ASHOK\\SQLEXPRESS0;Initial Catalog=DemoDataBase;User ID=ap;Password=ap@1234");
       
        // GET: UserInfo
        [Authorize]
        public ActionResult UserInfo()
        {
            return View();
        }
        // GET:Login this Action method simple return the Login View
        [HttpGet]
        public ActionResult Login()
        {
            return View();
        }
        //Post:When user click on the submit button then this method will call
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Login(LoginViewModel LoginViewModel)
        {
            if (IsValidUser(LoginViewModel.Email, LoginViewModel.Password))
            {
                FormsAuthentication.SetAuthCookie(LoginViewModel.Email, false);
                return RedirectToAction("UserInfo", "Account");
            }
            else
            {
                ModelState.AddModelError("", "Your Email and password is incorrect");
            }
            return View(LoginViewModel);
        }
        // GET:Register return view
        [HttpGet]
        public ActionResult Register()
        {
            return View();
        }
        // Post:Register 
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Register(RegistrationViewModel RegistrationViewModel)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    //checking if user already exist
                    if (!IsUserExist(RegistrationViewModel.Email))
                    {
                        string query = "insert into TblUsers values (@Name,@Email,@Password,@ContactNo)";
                        using (SqlCommand cmd = new SqlCommand(query, con))
                        {
                            cmd.Connection = con;
                            cmd.Parameters.AddWithValue("@Name", RegistrationViewModel.Name);
                            cmd.Parameters.AddWithValue("@Email", RegistrationViewModel.Email);
                            // encode password i'm using simple base64 you can use any more secure algo
                            cmd.Parameters.AddWithValue("@Password", Base64Encode(RegistrationViewModel.Password));
                            cmd.Parameters.AddWithValue("@ContactNo", RegistrationViewModel.ContactNo);
                            con.Open();
                            int i = cmd.ExecuteNonQuery();
                            con.Close();
                            if (i > 0)
                            {
                                FormsAuthentication.SetAuthCookie(RegistrationViewModel.Email, false);
                                return RedirectToAction("UserInfo", "Account");
                            }
                            else
                            {
                                ModelState.AddModelError("", "something went wrong try later!");
                            }
                        }
                    }
                    else
                    {
                        ModelState.AddModelError("", "User with same email already exist!");
                    }

                }
                else
                {
                    ModelState.AddModelError("", "Data is not correct");
                }
            }
            catch (Exception e)
            {
                ModelState.AddModelError("", e.Message);
            }
            return View();
        }
        public ActionResult LogOut()
        {
            FormsAuthentication.SignOut();
            return RedirectToAction("Index", "Home");        }

        private bool IsUserExist(string email)
        {
            bool IsUserExist = false;
            string query = "select * from TblUsers where Email=@email";
            using (SqlCommand cmd = new SqlCommand(query, con))
            {
                cmd.Parameters.AddWithValue("@email", email);
                SqlDataAdapter sda = new SqlDataAdapter(cmd);
                DataTable dt = new DataTable();
                sda.Fill(dt);
                con.Open();
                int i = cmd.ExecuteNonQuery();
                con.Close();
                if (dt.Rows.Count > 0)
                {
                    IsUserExist = true;
                }
            }
            return IsUserExist;
        }
        private bool IsValidUser(string email, string password)
        {
            var encryptpassowrd = Base64Encode(password);
            bool IsValid = false;
            string query = "select * from TblUsers where Email=@email and Password=@Password";
            using (SqlCommand cmd = new SqlCommand(query, con))
            {
                cmd.Parameters.AddWithValue("@Email", email);
                cmd.Parameters.AddWithValue("@Password", encryptpassowrd);
                SqlDataAdapter sda = new SqlDataAdapter(cmd);
                DataTable dt = new DataTable();
                sda.Fill(dt);
                con.Open();
                int i = cmd.ExecuteNonQuery();
                con.Close();
                if (dt.Rows.Count > 0)
                {
                    IsValid = true;
                }
            }
            return IsValid;
        }

        public static string Base64Encode(string plainText)
        {
            var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
            return System.Convert.ToBase64String(plainTextBytes);
        }
        public static string Base64Decode(string base64EncodedData)
        {
            var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData);
            return System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
        }
    }
}

AccountController class that handles user authentication and registration logic in an ASP.NET MVC application. 

  • SQL Connection: The con object represents a connection to a SQL Server database named "DemoDataBase" hosted on the server "ASHOK\SQLEXPRESS0". The credentials used for authentication are provided in the connection string.

Action Methods:

  • UserInfo: This method is decorated with the [Authorize] attribute, indicating that only authenticated users are allowed to access it. It returns a view.
  • Login: This method handles GET requests for the login page. It returns a view with a form for users to enter their credentials.
  • Login (overloaded): This method handles POST requests for the login page. It receives a LoginViewModel object containing the submitted credentials. If the user is valid, it sets an authentication cookie and redirects to the UserInfo action. Otherwise, it adds a model error and returns the login view.
  • Register: These methods handle GET and POST requests for the registration page. They receive a RegistrationViewModel object containing the user's registration information. If the data is valid and the user does not already exist, the user is inserted into the database, an authentication cookie is set, and the user is redirected to the UserInfo action. If the user already exists, an error is added to the model. If there is an exception during the registration process, an error message is added to the model.
  • LogOut: This method signs out the current user by removing the authentication cookie and redirects to the home page.

Helper Methods:

  • IsUserExist: This method checks if a user with the specified email already exists in the database.
  • IsValidUser: This method validates the user's credentials by checking if the provided email and password match an entry in the database.
  • Base64Encode and Base64Decode: These methods are used for encoding and decoding strings using Base64 encoding.
  • Data Access: Data access is performed using ADO.NET SqlCommand and SqlDataAdapter objects to execute SQL queries against the database.

AccountController provides functionality for user authentication (login, logout) and registration, interacting with a SQL Server database for data storage.

Step 5-Now Let’s create a View for each action method, right-click on each ActionMethod and click on add View with Use Layout Check selected.

If you checkmark “Use Layout” option then it automatically creates Master _Layout.cshtml View in the “Shared” folder and also create bootstrap files in your project.

After adding View for each ActionMethod your View folder should look like at the below image.

 

Step 6-Now Copy Paste the Below Code in Login and Registration View

Login.cshtml

@model MvcDemoProject.Models.LoginViewModel
@{
    ViewBag.Title = "Login";
}

<h2>Login</h2>
<div class="row">
    <div class="col-md-8">
        <section id="loginForm">
            @using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
            {
            @Html.AntiForgeryToken()
            <h4>Use a local account to log in.</h4>
            <hr />
            @Html.ValidationSummary(true, "", new { @class = "text-danger" })
            <div class="form-group">
                @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })
                <div class="col-md-10">
                    @Html.TextBoxFor(m => m.Email, new { @class = "form-control" })
                    @Html.ValidationMessageFor(m => m.Email, "", new { @class = "text-danger" })
                </div>
            </div>
            <div class="form-group">
                @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })
                <div class="col-md-10">
                    @Html.PasswordFor(m => m.Password, new { @class = "form-control" })
                    @Html.ValidationMessageFor(m => m.Password, "", new { @class = "text-danger" })
                </div>
            </div>
            <div class="form-group">
                <div class="col-md-offset-2 col-md-10">
                    <input type="submit" value="Log in" class="btn btn-default" />
                </div>
            </div>
            <p>
                @Html.ActionLink("Register as a new user", "Register")
            </p>
            }
        </section>
    </div>
</div>

Register.cshtml

@model MvcDemoProject.Models.RegistrationViewModel 
@{
    ViewBag.Title = "Register";
}
<h2>Register</h2>
@using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
    @Html.AntiForgeryToken()
    <h4>Create a new account.</h4>
    <hr />
    @Html.ValidationSummary("", new { @class = "text-danger" })
    <div class="form-group">
        @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.Email, new { @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Name, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.Name, new { @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.ContactNo, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.ContactNo, new { @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.PasswordFor(m => m.Password, new { @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" class="btn btn-default" value="Register" />
        </div>
    </div>
}

UserInfo.cshtml

@{
    ViewBag.Title = "UserInfo";
}

<h2>UserInfo</h2>
<h3>Hello User @HttpContext.Current.User.Identity.Name </h3>

_Layout.cshtml

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title - My ASP.NET Application</title>
    <link href="~/Content/Site.css" rel="stylesheet" type="text/css" />
    <link href="~/Content/bootstrap.min.css" rel="stylesheet" type="text/css" />
    <script src="~/Scripts/modernizr-2.6.2.js"></script>
    <style>
        .field-validation-error{
            color:red;
        }
    </style>
</head>
<body>
    <div class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                @if (Request.IsAuthenticated)
                {
                    <strong>@Html.Encode(User.Identity.Name)</strong>
                    <a href="@Url.Action("","")" class = "navbar-brand">Logout</a>
                }
                else
                {
                    <a href="@Url.Action("","")" class = "navbar-brand">Register</a>
                    <span> | </span>
                    <a href="@Url.Action("","")" class="navbar-brand">Login</a>
                }
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                </ul>
            </div>
        </div>
    </div>

    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>© @DateTime.Now.Year - My ASP.NET Application</p>
        </footer>
    </div>

    <script src="~/Scripts/jquery-1.10.2.min.js"></script>
    <script src="~/Scripts/bootstrap.min.js"></script>
</body>
</html>

Last and Final Step :

Copy Paste the Below Code in Web.config under <system.web> Tag for forms authenticaton.
<authentication mode="Forms">
      <forms defaultUrl="/Home/Index" loginUrl="/Home/Index" slidingExpiration="true" timeout="2880"></forms>
    </authentication>

 

Download Source Code