Introduction
In this blog, we will learn how to create a database for new registration using SQL server 2014. We will learn how to create registration page and login page using MVC and Entity framework. And also write a code for how to send email notification email after registration. How to activate email address and how to encrypt Password etc.
In this blog, I will explain the following topics,
- Registration
- Login
- Email Notification
- Email Activation
- Encrypt password or password hashing
- Generate email OTP
- Change password using OTP
Using MVC and entity framework and SQL server 2014
Step 1
First I will create a database table and the table name is UserM
Step 2
Create one MVC project using Visual Studio
Step 3
After creating project create one folder inside the project and name is DBContext and Add Entitydata Model in this folder.
Step 4
Create controller inside the controller folder with name Register. and write the below code to register the data. I am using Index ActionResult method for registration purpose, you can create another method. In this, I have included two methods one IsEmailExists and another SendEmailToUser. Both methods is shown below
// #region Registration post method for data save
[HttpPost]
public ActionResult Index(UserM objUsr) {
// email not verified on registration time
objUsr.EmailVerification = false;
//check email is exist or not in db.
var IsExists = IsEmailExists(objUsr.Email);
if (IsExists) {
ModelState.AddModelError("EmailExists", "This Email is already Exists Please enter other email");
return View("Index");
}
//it generate unique code
objUsr.ActivetionCode = Guid.NewGuid();
//password convert
objUsr.Password = encryptPassword.textToEncrypt(objUsr.Password);
objCon.UserMs.Add(objUsr);
objCon.SaveChanges();
//region Send Email verification links
SendEmailToUser(objUsr.Email, objUsr.ActivetionCode.ToString());
var message = "Registration Completed. Please check your email :" + objUsr.Email;
ViewBag.Message = message;
//endregion
return View("Registration");
}
// #endregion
public bool IsEmailExists(string eMail) {
var IsCheck = objCon.UserMs.Where(email => email.Email == eMail).FirstOrDefault();
return IsCheck != null;
}
// #endregion
//#region Send Email notification on registered email id
public void SendEmailToUser(string emailId, string activationCode) {
//var GenarateUserVerificationLink = "/Register/UserVerification/" + activationCode;
//var link = Request.Url.AbsoluteUri.Replace(Request.Url.PathAndQuery, GenarateUserVerificationLink);
var link = "https://localhost:44329/Register/UserVerification/" + activationCode;
var fromMail = new MailAddress("Your email id ", "R.R Reaserch and Development"); // set your email
var fromEmailpassword = "your email id password"; // Set your password
var toEmail = new MailAddress(emailId);
var smtp = new SmtpClient();
smtp.Host = "smtp.gmail.com";
smtp.Port = 587;
smtp.EnableSsl = true;
smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
smtp.UseDefaultCredentials = false;
smtp.Credentials = new NetworkCredential(fromMail.Address, fromEmailpassword);
var Message = new MailMessage(fromMail, toEmail);
Message.Subject = "Registration Completed";
Message.Body = "<br/> Your registration completed succesfully." + "<br/> please click on the below link for account verification" + "<br/><br/><a href=" + link + ">" + link + "</a>";
Message.IsBodyHtml = true;
smtp.Send(Message);
}
Step 5
Now add View forregistration
@model MVCProjectPractics.Models.UserRegistration
@{
ViewBag.Title = "Index";
}
@using (Html.BeginForm("Index","Register",FormMethod.Post))
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h3 style="text-align:center">User Registration</h3>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@*@Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label col-md-2" })*@
<span class="control-label col-md-2"><b>First Name:</b></span>
<div class="col-md-10">
@Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.FirstName, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@*@Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label col-md-2" })*@
<span class="control-label col-md-2"><b>Last Name:</b></span>
<div class="col-md-10">
@Html.EditorFor(model => model.LastName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.LastName, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<span class="control-label col-md-2"><b>Email:</b></span>
<div class="col-md-10">
@Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" })
@Html.ValidationMessage("EmailExists", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@*@Html.LabelFor(model => model.Password, htmlAttributes: new { @class = "control-label col-md-2" })*@
<span class="control-label col-md-2"><b>Password:</b></span>
<div class="col-md-10">
@Html.EditorFor(model => model.Password, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Password, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@*@Html.LabelFor(model => model.ConfirmPassword, htmlAttributes: new { @class = "control-label col-md-2" })*@
<span class="control-label col-md-2"><b>Confirm Password:</b></span>
<div class="col-md-10">
@Html.EditorFor(model => model.ConfirmPassword, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.ConfirmPassword, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Register" class="btn btn-success" />
<input type="submit" value="Register" class="btn btn-danger" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
Now run this project and output look like below
After providing the details and click on the register button please check your email id.
After Registration check the database it will display like below result.
Step 6
Now create Login Action inside the controller
public ActionResult Login() {
return View();
}
[HttpPost]
public ActionResult Login(UserLogin LgnUsr) {
var _passWord = encryptPassword.textToEncrypt(LgnUsr.Password);
bool Isvalid = objCon.UserMs.Any(x => x.Email == LgnUsr.EmailId && x.EmailVerification == true && x.Password == _passWord);
if (Isvalid) {
int timeout = LgnUsr.Rememberme ? 60 : 5; // Timeout in minutes, 60 = 1 hour.
var ticket = new FormsAuthenticationTicket(LgnUsr.EmailId, false, timeout);
string encrypted = FormsAuthentication.Encrypt(ticket);
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encrypted);
cookie.Expires = System.DateTime.Now.AddMinutes(timeout);
cookie.HttpOnly = true;
Response.Cookies.Add(cookie);
return RedirectToAction("Index", "UserDash");
} else {
ModelState.AddModelError("", "Invalid Information... Please try again!");
}
return View();
}
Login View
@model MVCProjectPractics.Models.UserLogin
@{
ViewBag.Title = "Login";
}
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h3 style="text-align:center">User Login</h3>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.EmailId, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.EmailId, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.EmailId, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Password, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Password, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Password, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Rememberme, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
<div class="checkbox">
@Html.EditorFor(model => model.Rememberme)
@Html.ValidationMessageFor(model => model.Rememberme, "", new { @class = "text-danger" })
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Login" class="btn btn-primary" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Registration", "Index") ||
@Html.ActionLink("Reset Passward", "ForgetPassword")
</div>
Login Output
Step 7
Now write the below code for Reset Password with email OTP
// startregion Change password details
public ActionResult ForgetPassword() {
return View();
}
[HttpPost]
public ActionResult ForgetPassword(ForgetPassword pass) {
var IsExists = IsEmailExists(pass.EmailId);
if (!IsExists) {
ModelState.AddModelError("EmailNotExists", "This email is not exists");
return View();
}
var objUsr = objCon.UserMs.Where(x => x.Email == pass.EmailId).FirstOrDefault();
// Genrate OTP
string OTP = GeneratePassword();
objUsr.ActivetionCode = Guid.NewGuid();
objUsr.OTP = OTP;
objCon.Entry(objUsr).State = System.Data.Entity.EntityState.Modified;
objCon.SaveChanges();
ForgetPasswordEmailToUser(objUsr.Email, objUsr.ActivetionCode.ToString(), objUsr.OTP);
ViewBag.Message = "Password reset links has been sent on your email id please check email and click on link";
return RedirectToAction("ForgetPassword", "UserDash");
}
public void ForgetPasswordEmailToUser(string emailId, string activationCode, string OTP) {
//var GenarateUserVerificationLink = "/Register/UserVerification/" + activationCode;
//var link = Request.Url.AbsoluteUri.Replace(Request.Url.PathAndQuery, GenarateUserVerificationLink);
var link = "https://localhost:44329/Register/ChangePassword/" + activationCode;
var fromMail = new MailAddress("youremail id", "R.R Reaserch and Development"); // set your email
var fromEmailpassword = "your password"; // Set your password
var toEmail = new MailAddress(emailId);
var smtp = new SmtpClient();
smtp.Host = "smtp.gmail.com";
smtp.Port = 587;
smtp.EnableSsl = true;
smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
smtp.UseDefaultCredentials = false;
smtp.Credentials = new NetworkCredential(fromMail.Address, fromEmailpassword);
var Message = new MailMessage(fromMail, toEmail);
Message.Subject = "Registration Completed-Demo";
Message.Body = "<br/> please click on the below link for change the password" + "<br/><br/><a href=" + link + ">" + link + "</a>" + "<br> OPT for password change:" + OTP;
Message.IsBodyHtml = true;
smtp.Send(Message);
}
public string GeneratePassword() {
string OTPLength = "4";
string OTP = string.Empty;
string Chars = string.Empty;
Chars = "1,2,3,4,5,6,7,8,9,0";
char[] seplitChar = {
','
};
string[] arr = Chars.Split(seplitChar);
string NewOTP = "";
string temp = "";
Random rand = new Random();
for (int i = 0; i < Convert.ToInt32(OTPLength); i++) {
temp = arr[rand.Next(0, arr.Length)];
NewOTP += temp;
OTP = NewOTP;
}
return OTP;
}
//change password
Step 8
Create View for forget password
@model MVCProjectPractics.Models.ForgetPassword
@{
ViewBag.Title = "ForgetPassword";
}
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h3 style="text-align:center">Forget Password</h3>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.EmailId, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.EmailId, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.EmailId, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Reset Password" class="btn btn-primary" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
Step 9
Please check email for forget the password link and OTP
Step 10
Write the method for changing the password using the received OTP inside the Register controller
//change password
public ActionResult ChangePassword() {
return View();
}
[HttpPost]
public ActionResult ChangePassword(ChangePassword changePass, UserM objUsr) {
string password = changePass.Password;
objUsr = objCon.UserMs.Where(x => x.OTP == changePass.OTP).FirstOrDefault();
objUsr.Password = encryptPassword.textToEncrypt(password);
objCon.Entry(objUsr).State = System.Data.Entity.EntityState.Modified;
objCon.SaveChanges();
ViewBag.Message = "Password has been change successfully..!";
return RedirectToAction("PasswordChange", "UserDash");
}
//Endregion
Step 11
Create View to Change the password,
@model MVCProjectPractics.Models.ChangePassword
@{
ViewBag.Title = "ChangePassword";
}
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h3 style="text-align:center">Change Password</h3>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.OTP, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.OTP, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.OTP, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Password, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Password, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Password, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.ConfirmPassword, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.ConfirmPassword, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.ConfirmPassword, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Change Password" class="btn btn-primary" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Login", "Login")
</div>
All Models Code is below,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data;
using System.Data.SqlClient;
namespace MVCProjectPractics.Models {
[Table("UserM")]
public class ChangePassword {
[Key]
public int UserId {
get;
set;
}
[Required(AllowEmptyStrings = false, ErrorMessage = "OTP is requierd")]
public string OTP {
get;
set;
}
[Required(AllowEmptyStrings = false, ErrorMessage = "Password is requierd")]
[DataType(DataType.Password)]
[MinLength(6, ErrorMessage = "Need min 6 char")]
public string Password {
get;
set;
}
[Required(AllowEmptyStrings = false, ErrorMessage = "Confirm Password is requierd")]
[DataType(DataType.Password)]
[Compare("Password", ErrorMessage = "Confirm Password should match with Password")]
public string ConfirmPassword {
get;
set;
}
}
}
User Registration
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Data.SqlClient;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace MVCProjectPractics.Models {
[Table("[UserM]")]
public class UserRegistration {
[Key]
public int UserId {
get;
set;
}
[Required(AllowEmptyStrings = false, ErrorMessage = "First Name is requierd")]
public string FirstName {
get;
set;
}
[Required(AllowEmptyStrings = false, ErrorMessage = "Last Name is requierd")]
public string LastName {
get;
set;
}
[Required(AllowEmptyStrings = false, ErrorMessage = "Email ID is requierd")]
public string Email {
get;
set;
}
[Required(AllowEmptyStrings = false, ErrorMessage = "Password is requierd")]
[DataType(DataType.Password)]
[MinLength(6, ErrorMessage = "Need min 6 character")]
public string Password {
get;
set;
}
[Required(AllowEmptyStrings = false, ErrorMessage = "Confirm Password is requierd")]
[DataType(DataType.Password)]
[Compare("Password", ErrorMessage = "Confirm Password should match with Password")]
public string ConfirmPassword {
get;
set;
}
}
}
Password Encrypted
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
namespace MVCProjectPractics.Models {
public class encryptPassword {
public static string textToEncrypt(string paasWord) {
return Convert.ToBase64String(System.Security.Cryptography.SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(paasWord)));
}
}
}
Forget Password
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Data.SqlClient;
using System.ComponentModel.DataAnnotations.Schema;
namespace MVCProjectPractics.Models {
[Table("[UserM]")]
public class ForgetPassword {
[Key]
public int UserId {
get;
set;
}
[Display(Name = "User Email ID")]
[Required(AllowEmptyStrings = false, ErrorMessage = "User Email Id Required")]
public string EmailId {
get;
set;
}
}
}
User Login
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace MVCProjectPractics.Models {
[Table("[UserM]")]
public class UserLogin {
[Key]
public int UserId {
get;
set;
}
[Display(Name = "User Email ID")]
[Required(AllowEmptyStrings = false, ErrorMessage = "User Email Id Required")]
public string EmailId {
get;
set;
}
[Display(Name = "Password")]
[DataType(DataType.Password)]
[Required(AllowEmptyStrings = false, ErrorMessage = "Password Required")]
public string Password {
get;
set;
}
[Display(Name = "Remember Me")]
public bool Rememberme {
get;
set;
}
}
}