In this article I will explain with an example, how to build a simple user Registration and Login forms in ASP.Net MVC Razor.
The user Registration and Login forms will be built using SQL Server Database.
The Database connection and operations for user Registration and Login forms will be performed using Entity Framework in ASP.Net MVC Razor.
Configuring Bundles and enabling Client Side Validation
The Form validation will be performed on Client Side using Model Data Annotations and jQuery.
Please refer the following article for complete information on how to configure Bundles and enable Client Side validation in ASP.Net MVC project.
Note: By default the validation done using Data Annotation attributes is Server Side. And hence to make it work Client Side, the Client Side validation must be enabled.
Database
For this article I have created a new database named LoginDB which contains the following table named Users in it.
Note: You can download the database table SQL by clicking the download link below.
Download SQL file
Stored Procedures
User Registration Stored Procedure
The following stored procedure is used to insert the user details such as username, password and email address.
The stored procedure first checks whether the username supplied already exists, if yes then it will return negative 1 (-1) value.
Then the stored procedure checks whether the email address supplied already exists, if yes then it will return negative 2 (-2) value.
If both username and email address are valid then the record will be inserted and the auto-generated UserId will be returned by the stored procedure.
CREATE PROCEDURE [dbo].[Insert_User]
@Username NVARCHAR(20),
@Password NVARCHAR(20),
@Email NVARCHAR(30)
AS
BEGIN
SET NOCOUNT ON;
IF EXISTS(SELECT UserId FROM Users WHERE Username = @Username)
BEGIN
SELECT -1 AS UserId -- Username exists.
END
ELSE IF EXISTS(SELECT UserId FROM Users WHERE Email = @Email)
BEGIN
SELECT -2 AS UserId -- Email exists.
END
ELSE
BEGIN
INSERT INTO [Users]
([Username]
,[Password]
,[Email]
,[CreatedDate])
VALUES
(@Username
,@Password
,@Email
,GETDATE())
SELECT SCOPE_IDENTITY() AS UserId -- UserId
END
END
User Login Stored Procedure
The following stored procedure is used to validate the user credentials, this stored procedure first checks whether the username and password are correct else returns -1.
If the username and password are correct but the user has not been activated then the code returned is -2.
If the username and password are correct and the user account has been activated then UserId of the user is returned by the stored procedure.
CREATE PROCEDURE [dbo].[Validate_User]
@Username NVARCHAR(20),
@Password NVARCHAR(20)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @UserId INT, @LastLoginDate DATETIME
SELECT @UserId = UserId, @LastLoginDate = LastLoginDate
FROM Users WHERE Username = @Username AND [Password] = @Password
IF @UserId IS NOT NULL
BEGIN
IF NOT EXISTS(SELECT UserId FROM UserActivation WHERE UserId = @UserId)
BEGIN
UPDATE Users
SET LastLoginDate = GETDATE()
WHERE UserId = @UserId
SELECT @UserId [UserId] -- User Valid
END
ELSE
BEGIN
SELECT -2 -- User not activated.
END
END
ELSE
BEGIN
SELECT -1 -- User invalid.
END
END
Configuring Entity Framework
You will need to configure the Entity Framework in order to connect to the database.
Once you reach the Database Objects selection step, you will need to select the Users table and the Insert_User and Validate_User Stored Procedures as shown below.
Once the Finish button is clicked, the UserModel is ready as shown below.
Mapping the Stored Procedures in Entity Framework
The next step is to map the Stored Procedures with Entity Framework.
User Registration Stored Procedure mapping
In order to map the Insert_User Stored Procedure with the Insert operation of Entity Framework, you will need to Right Click, the Entity Model and select Stored Procedure Mapping as shown below.
Once the Mapping Details window is open, you need to click the <Select Insert Function> Dropdown and select the Insert_User Stored Procedure.
Finally from the Result Column Bindings, click on Add Result Binding and type in the value UserId and then click on the next Cell in the Operator column and automatically it will be display the UserId property name in the corresponding Cell of the Property column.
Note: The ALIAS for the returning Column in the Insert_User Stored Procedure is UserId and hence the same is used while mapping the returning value to the property.
User Login Stored Procedure mapping
The next step is to map the Validate_User Stored Procedure used for the validation of the User credentials using Entity Framework. In order to do so, to Right click on the User Table and click on Add New option and then Function Import option from the Context menu.
The above action will open the Add Function Import Dialog window. Here you will need to
1. Function Import Name: Specify the name of the method which will be used to execute the Stored Procedure.
2. Stored Procedure / Function Name: Select the Stored Procedure / Function to be imported.
3. Returns a Collection Of: The Stored Procedure used in this article returns a Scalar value and hence the same is selected.
Finally once all the above is done, simply click the OK button.
Model
There is no need of Model class for this project as we will be using the Entity Framework Model class which is automatically generated. You will find it in the Solution Explorer as shown below.
Now you will need to open the Model class User.cs and it will have the following contents.
namespace User_Registration_MVC
{
using System;
using System.Collections.Generic;
public partial class User
{
public int UserId { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string Email { get; set; }
public System.DateTime CreatedDate { get; set; }
public Nullable<System.DateTime> LastLoginDate { get; set; }
}
}
Now you will need to add the validation Data Annotations and also two additional properties ConfirmPassword and RememberMe as shown below.
Note: You will need to keep a copy of this class before you regenerate Entity Framework model or make changes to it as all your changes will be overwritten.
namespace User_Registration_MVC
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
public partial class User
{
public int UserId { get; set; }
[Required(ErrorMessage = "Required.")]
public string Username { get; set; }
[Required(ErrorMessage = "Required.")]
public string Password { get; set; }
[Required(ErrorMessage = "Required.")]
[Compare("Password", ErrorMessage = "Passwords do not match.")]
public string ConfirmPassword { get; set; }
[Required(ErrorMessage = "Required.")]
[EmailAddress(ErrorMessage = "Invalid email address.")]
public string Email { get; set; }
public System.DateTime CreatedDate { get; set; }
public Nullable<System.DateTime> LastLoginDate { get; set; }
public bool RememberMe { get; set; }
}
}
Note: For explanation of the various Data Annotations used for Required, Email and Confirm Password validations, please refer my articles:
Namespaces
You will need to import the following namespace.
using System.Web.Security;
Controllers
User Registration Controller
The Controller consists of two Action methods.
Action method for handling GET operation
Inside this Action method, simply the View is returned.
Action method for handling POST operation
This action method handles the POST operation and when the form is submitted, the object of the User model class is sent to this method.
The received User Model class object is inserted into the database using the Entity Framework and the value returned from the Insert_User Stored Procedure is captured in the UserId property of the User Model class object.
As discussed earlier, the Insert_User Stored Procedure will return negative 1 (-1), negative 2 (-2) or UserId of the inserted record.
Based on the returned values, a string message is set in the ViewBag object which will be later on displayed in View using JavaScript Alert Message Box.
public class HomeController : Controller
{
// GET: Registration
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(User user)
{
UsersEntities usersEntities = new UsersEntities();
usersEntities.Users.Add(user);
usersEntities.SaveChanges();
string message = string.Empty;
switch (user.UserId)
{
case -1:
message = "Username already exists.\\nPlease choose a different username.";
break;
case -2:
message = "Supplied email address has already been used.";
break;
default:
message = "Registration successful.\\nUser Id: " + user.UserId.ToString();
break;
}
ViewBag.Message = message;
return View(user);
}
}
User Login Controller
The Controller consists of four Action methods.
Action method for handling GET operation for Login
Inside this Action method, simply the View is returned. This Action method is decorated with AllowAnonymous Data Annotation which signifies Form Based authentication that this method can be accessed without authentication.
Action method for handling GET operation for Profile
Inside this Action method, simply the View is returned. This Action method is decorated with Authorize Data Annotation which signifies Form Based authentication that this method requires authentication to be accessed.
Action method for handling POST operation for Login
Inside this Action method, the ValidateUser method is called which executes the Stored Procedure that validates the User’s credentials.
The status returned from the Stored Procedure is captured and if the value is not -1 (Username or password incorrect) or -2 (Account not activated) then the user is redirected to the Profile View after setting the Forms Authentication Cookie.
For the status -1 and -2, the message is displayed to the user using ViewBag object.
Action method for handling POST operation for Logout
Inside this Action method, the Signout method of Forms Authentication is called which clears the Forms Authentication Cookie and the user is redirected to the Index View.
public class HomeController : Controller
{
[AllowAnonymous]
public ActionResult Index()
{
return View();
}
[Authorize]
public ActionResult Profile()
{
return View();
}
[HttpPost]
[AllowAnonymous]
public ActionResult Index(User user)
{
UsersEntities usersEntities = new UsersEntities();
int? userId = usersEntities.ValidateUser(user.Username, user.Password).FirstOrDefault();
string message = string.Empty;
switch (userId.Value)
{
case -1:
message = "Username and/or password is incorrect.";
break;
case -2:
message = "Account has not been activated.";
break;
default:
FormsAuthentication.SetAuthCookie(user.Username, user.RememberMe);
return RedirectToAction("Profile");
}
ViewBag.Message = message;
return View(user);
}
[HttpPost]
[Authorize]
public ActionResult Logout()
{
FormsAuthentication.SignOut();
return RedirectToAction("Index");
}
}
Views
User Registration View
Inside the View, in the very first line the User Model class is declared as Model for the View.
The View consists of an HTML Form which has been created using the Html.BeginForm method with the following parameters.
ActionName – Name of the Action. In this case the name is Index.
ControllerName – Name of the Controller. In this case the name is Home.
FormMethod – It specifies the Form Method i.e. GET or POST. In this case it will be set to POST.
Inside the View, the following three HTML Helper functions are used:-
1. Html.TextBoxFor – Creating a TextBox for the Model property.
2. Html.PasswordFor – Creating a Password TextBox for the Model property.
3. Html.ValidationMessageFor – Displaying the Validation message for the property.
There is also Submit button which when clicked, the Form gets submitted.
The jQuery and the jQuery Validation script bundles are rendered at the end of the Model using the Scripts.Render function.
ViewBag’s Message object is checked for NULL and if it is not NULL then the string message is displayed using JavaScript Alert Message Box.
@model User_Registration_MVC.User
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width"/>
<title>Index</title>
<style type="text/css">
body {
font-family: Arial;
font-size: 10pt;
}
table {
border: 1px solid #ccc;
border-collapse: collapse;
}
table th {
background-color: #F7F7F7;
color: #333;
font-weight: bold;
}
table th, table td {
padding: 5px;
border: 1px solid #ccc;
}
.error {
color: red;
}
</style>
</head>
<body>
@using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<th colspan="3">
Registration
</th>
</tr>
<tr>
<td>
Username
</td>
<td>
@Html.TextBoxFor(m => m.Username)
</td>
<td>
@Html.ValidationMessageFor(m => m.Username, "", new { @class = "error" })
</td>
</tr>
<tr>
<td>
Password
</td>
<td>
@Html.PasswordFor(m => m.Password)
</td>
<td>
@Html.ValidationMessageFor(m => m.Password, "", new { @class = "error" })
</td>
</tr>
<tr>
<td>
Confirm Password
</td>
<td>
@Html.PasswordFor(m => m.ConfirmPassword)
</td>
<td>
@Html.ValidationMessageFor(m => m.ConfirmPassword, "", new { @class = "error" })
</td>
</tr>
<tr>
<td>
Email
</td>
<td>
@Html.TextBoxFor(m => m.Email)
</td>
<td>
@Html.ValidationMessageFor(m => m.Email, "", new { @class = "error" })
</td>
</tr>
<tr>
<td></td>
<td>
<input type="submit" value="Submit"/>
</td>
<td></td>
</tr>
</table>
}
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/jqueryval")
@if (@ViewBag.Message != null)
{
<script type="text/javascript">
$(function () {
alert("@ViewBag.Message")
});
</script>
}
</body>
</html>
User Login Views
The User Login section has two Views i.e. Index and Profile.
Index
Inside the View, in the very first line the User Model class is declared as Model for the View.
The View consists of an HTML Form which has been created using the Html.BeginForm method with the following parameters.
ActionName – Name of the Action. In this case the name is Index.
ControllerName – Name of the Controller. In this case the name is Home.
FormMethod – It specifies the Form Method i.e. GET or POST. In this case it will be set to POST.
Inside the View, the following four HTML Helper functions are used:-
1. Html.TextBoxFor – Creating a TextBox for the Model property.
2. Html.PasswordFor – Creating a Password TextBox for the Model property.
3. Html.ValidationMessageFor – Displaying the Validation message for the property.
4. Html.CheckBoxFor – Creating a CheckBox for the Model property.
There is also Submit button which when clicked, the Form gets submitted.
The jQuery and the jQuery Validation script bundles are rendered at the end of the Model using the Scripts.Render function.
ViewBag’s Message object is checked for NULL and if it is not NULL then the string message is displayed using JavaScript Alert Message Box.
@model User_Login_MVC.User
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width"/>
<title>Index</title>
<style type="text/css">
body {
font-family: Arial;
font-size: 10pt;
}
table {
border: 1px solid #ccc;
border-collapse: collapse;
}
table th {
background-color: #F7F7F7;
color: #333;
font-weight: bold;
}
table th, table td {
padding: 5px;
border: 1px solid #ccc;
}
.error {
color: red;
}
</style>
</head>
<body>
@using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<th colspan="3">
Login
</th>
</tr>
<tr>
<td>
Username
</td>
<td>
@Html.TextBoxFor(m => m.Username)
</td>
<td>
@Html.ValidationMessageFor(m => m.Username, "", new { @class = "error" })
</td>
</tr>
<tr>
<td>
Password
</td>
<td>
@Html.PasswordFor(m => m.Password)
</td>
<td>
@Html.ValidationMessageFor(m => m.Password, "", new { @class = "error" })
</td>
</tr>
<tr>
<td>
Remember Me
</td>
<td>
@Html.CheckBoxFor(m => m.RememberMe)
</td>
<td>
</td>
</tr>
<tr>
<td></td>
<td>
<input type="submit" value="Submit"/>
</td>
<td></td>
</tr>
</table>
}
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/jqueryval")
@if (@ViewBag.Message != null)
{
<script type="text/javascript">
$(function () {
alert("@ViewBag.Message")
});
</script>
}
</body>
</html>
Profile
The Profile View displays the name of the Current Logged in User and it also consists of an HTML Form with an HTML Anchor link for Logout functionality.
When the Logout link is clicked, the Form gets submitted and the Logout Action method gets called.
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width"/>
<title>Profile</title>
<style type="text/css">
body {
font-family: Arial;
font-size: 10pt;
}
</style>
</head>
<body>
<div>
Welcome
<b>@HttpContext.Current.User.Identity.Name</b>
<br/>
<br/>
@using (Html.BeginForm("Logout", "Home", FormMethod.Post))
{
<a href="javascript:;" onclick="document.forms[0].submit();">Logout</a>
}
</div>
</body>
</html>
Web.Config Configuration
You will need to add the following configuration in the Web.Config file in the <system.web> section.
<authentication mode="Forms">
<forms defaultUrl="/Home/Profile" loginUrl="/Home/Index" slidingExpiration="true" timeout="2880"></forms>
</authentication>
Screenshots
User Registration
User Login
Downloads