How to Make Custom Login, Register, and Logout in MVC 4 Using Razor and EF

In this article you will learn how to make login, register, and logout screens with real-world functionality using Razor and Entity Framework data models.

What is Entity Framework

Entity Framework (EF) is an object-relational mapper that enables .NET developers to work with relational data using domain-specific objects. It eliminates the need for most of the data-access code that developers usually need to write. For more see: http://msdn.microsoft.com/en-us/data/ef.aspx

What is MVC?

The Model-View-Controller (MVC) pattern separates the modeling of the domain, the presentation, and the actions based on user input into three separate classes [Burbeck92].

Model

The model manages the behavior and data of the application domain, responds to requests for information about its state (usually from the view), and responds to instructions to change state (usually from the controller).

View

The view manages the display of information.

Controller

The controller interprets the mouse and keyboard inputs from the user, informing the model and/or the view to change as appropriate.

Getting Started

  1. Create a new project; first open Visual Studio 2012
  2. Then go to "File" => "New" => "Project..."
  3. Select Web in installed templates
  4. Select "ASP.NET MVC 4 Web Application"
  5. Enter the name and choose the location
  6. Click "OK"

Now add a new ADO.NET Entity data Model.

img1.jpg
Image 1.

To learn how to configure an ADO.NET Entity Data Model please read this article-

http://www.c-sharpcorner.com/uploadfile/raj1979/building-Asp-Net-mvc-web-applications-using-ado-net-entity-data-model/

So let's proceed without wasting time, here is my data model scenario:

img2.jpg
Image 2.

This is my model class that is generated when we configure the data model, I just made slight changes.

  1. //------------------------------------------------------------------------------  
  2. // <auto-generated>  
  3. //    This code was generated from a template.  
  4. //  
  5. //    Manual changes to this file may cause unexpected behavior in your application.  
  6. //    Manual changes to this file will be overwritten if the code is regenerated.  
  7. // </auto-generated>  
  8. //------------------------------------------------------------------------------  
  9.    
  10. namespace LoginInMVC4WithEF.Models  
  11. {  
  12.     using System;  
  13.     using System.Collections.Generic;  
  14.     using System.ComponentModel.DataAnnotations;  
  15.      
  16.     public partial class Registration  
  17.     {  
  18.         public int UserId { get; set; }  
  19.         [Required]  
  20.         [EmailAddress]  
  21.         [StringLength(150)]  
  22.         [Display(Name = "Email Address: ")]  
  23.         public string Email { get; set; }  
  24.    
  25.         [Required]  
  26.         [DataType(DataType.Password)]  
  27.         [StringLength(150, MinimumLength = 6)]  
  28.         [Display(Name = "Password: ")]  
  29.         public string Password { get; set; }  
  30.    
  31.         public string PasswordSalt { get; set; }  
  32.    
  33.         [Required]  
  34.         [Display(Name = "First Name: ")]  
  35.         public string FirstName { get; set; }  
  36.    
  37.         [Required]  
  38.         [Display(Name = "Last Name: ")]  
  39.         public string LastName { get; set; }  
  40.         public string UserType { get; set; }  
  41.         public System.DateTime CreatedDate { get; set; }  
  42.         public bool IsActive { get; set; }  
  43.         public string IPAddress { get; set; }  
  44.    }  

This is my context class, again this is also generated by data model.

  1. public partial class UserEntities2 : DbContext  
  2. {  
  3.     public UserEntities2()  
  4.         : base("name=UserEntities2")  
  5.     {  
  6.     }  
  7.    
  8.     protected override void OnModelCreating(DbModelBuilder modelBuilder)  
  9.     {  
  10.         throw new UnintentionalCodeFirstException();  
  11.     }  
  12.    
  13.     public DbSet<Registration> Registrations { get; set; }  
  14. }  

Now to add a controller.


img3.jpg
Image 3.

Add namespaces in the controller class:

  1. using System.Web.Security;  
  2. using LoginInMVC4WithEF.Models;  
  3.   
  4. Now add the following functions and methods.  
  5.    
  6. //  
  7. // GET: /User/  
  8. public ActionResult Index()  
  9. {  
  10.     return View();  
  11. }  
  12.          
  13. [HttpGet]         
  14. public ActionResult LogIn()  
  15. {  
  16.     return View();  
  17. }  
  18.          
  19. [HttpPost]         
  20. public ActionResult LogIn(Models.Registration userr)  
  21. {  
  22. //if (ModelState.IsValid)  
  23. //{  
  24.     if (IsValid(userr.Email, userr.Password))  
  25.     {  
  26.         FormsAuthentication.SetAuthCookie(userr.Email, false);  
  27.         return RedirectToAction("Index""Home");  
  28.     }  
  29.     else  
  30.     {  
  31.         ModelState.AddModelError("""Login details are wrong.");  
  32.     }  
  33.     return View(userr);  
  34. }  
  35.          
  36. [HttpGet]         
  37. public ActionResult Register()  
  38. {  
  39.     return View();  
  40. }  
  41.    
  42. [HttpPost]        
  43. public ActionResult Register(Models.Registration user)  
  44. {  
  45.     try  
  46.     {  
  47.         if (ModelState.IsValid)  
  48.         {  
  49.             using (var db = new LoginInMVC4WithEF.Models.UserEntities2())  
  50.             {  
  51.                 var crypto = new SimpleCrypto.PBKDF2();  
  52.                 var encrypPass = crypto.Compute(user.Password);  
  53.                 var newUser = db.Registrations.Create();  
  54.                 newUser.Email = user.Email;  
  55.                 newUser.Password = encrypPass;  
  56.                 newUser.PasswordSalt = crypto.Salt;  
  57.                 newUser.FirstName = user.FirstName;  
  58.                 newUser.LastName = user.LastName;  
  59.                 newUser.UserType = "User";  
  60.                 newUser.CreatedDate = DateTime.Now;  
  61.                 newUser.IsActive = true;  
  62.                 newUser.IPAddress = "642 White Hague Avenue";  
  63.                 db.Registrations.Add(newUser);  
  64.                 db.SaveChanges();  
  65.                 return RedirectToAction("Index""Home");  
  66.             }  
  67.         }  
  68.         else  
  69.         {  
  70.             ModelState.AddModelError("""Data is not correct");  
  71.         }  
  72.     }  
  73.     catch (DbEntityValidationException e)  
  74.     {  
  75.         foreach (var eve in e.EntityValidationErrors)  
  76.         {  
  77.             Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",  
  78.                 eve.Entry.Entity.GetType().Name, eve.Entry.State);  
  79.             foreach (var ve in eve.ValidationErrors)  
  80.             {  
  81.                 Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",  
  82.                     ve.PropertyName, ve.ErrorMessage);  
  83.             }  
  84.         }  
  85.         throw;  
  86.     }  
  87.     return View();  
  88. }  
  89.          
  90. public ActionResult LogOut()  
  91. {  
  92.     FormsAuthentication.SignOut();  
  93.     return RedirectToAction("Index""Home");  
  94. }  
  95.    
  96. private bool IsValid(string email, string password)  
  97. {  
  98.     var crypto = new SimpleCrypto.PBKDF2();  
  99.     bool IsValid = false;  
  100.    
  101.     using (var db = new LoginInMVC4WithEF.Models.UserEntities2())  
  102.     {  
  103.         var user = db.Registrations.FirstOrDefault(u => u.Email == email);  
  104.         if (user != null)  
  105.         {  
  106.             if (user.Password == crypto.Compute(password, user.PasswordSalt))  
  107.             {  
  108.                 IsValid = true;  
  109.             }  
  110.         }  
  111.     }  
  112.     return IsValid;  
  113. }   

There I have functions and methods for index page and login, logout, register and isvalid, now let's make some change in "_Layout.vshtml". Add the following div:

  1. <div style="width:auto; background-color:aqua">  
  2.         @if (Request.IsAuthenticated)  
  3.         {  
  4.             <strong>@Html.Encode(User.Identity.Name)</strong>  
  5.             @Html.ActionLink("Log Out""Logout""User")  
  6.         }  
  7.         else  
  8.         {  
  9.             @Html.ActionLink("Register""Register""User")  
  10.             <span> | </span>  
  11.             @Html.ActionLink("Log In""Login""User")  
  12.         }  
  13. </div>  

Now let's add views for presentation.

The best way to add a view is to right-click on the controller's method name and then right-click and "Add View" and select the view engine type and select strongly-typed view and use the layout master page and click "Add".

img4.jpg
Image 4.

LogIn.cshtml

  1. @model LoginInMVC4WithEF.Models.Registration  
  2.    
  3. @{  
  4.     ViewBag.Title = "LogIn";  
  5.     Layout = "~/Views/Shared/_Layout.cshtml";  
  6. }  
  7.    
  8. <h2>LogIn</h2>  
  9. @using (Html.BeginForm())  
  10. {  
  11.     @Html.ValidationSummary(true"Login Failed, check details");  
  12.     <div>  
  13.         <fieldset>  
  14.             <legend>Login Form</legend>  
  15.             <div class="editor-label">@Html.LabelFor(u=> u.Email)</div>  
  16.             <div class="editor-field">@Html.TextBoxFor(u=> u.Email)  
  17.                 @Html.ValidationMessageFor(u=> u.Email)  
  18.             </div>  
  19.             <div class="editor-label">@Html.LabelFor(u=> u.Password)</div>  
  20.             <div  class="editor-field">@Html.PasswordFor(u=> u.Password)  
  21.                 @Html.ValidationMessageFor(u=> u.Password)  
  22.             </div>  
  23.             <input type="submit" value="Log In" />  
  24.         </fieldset>  
  25.     </div>  
  26. }  

Register.cshtml

  1. @model LoginInMVC4WithEF.Models.Registration  
  2. @{  
  3.     ViewBag.Title = "Register";  
  4.     Layout = "~/Views/Shared/_Layout.cshtml";  
  5. }  
  6.    
  7. <h2>Register</h2>  
  8. @using (Html.BeginForm())  
  9. {  
  10.     @Html.ValidationSummary(true"Registeration Failed, fields.");  
  11.     <div>  
  12.         <fieldset>  
  13.             <legend>Register Form</legend>  
  14.             <div class="editor-label">@Html.LabelFor(u => u.Email)</div>  
  15.             <div class="editor-field">@Html.TextBoxFor(u => u.Email)  
  16.                 @Html.ValidationMessageFor(u => u.Email)  
  17.             </div>  
  18.             <div class="editor-label">@Html.LabelFor(u => u.Password)</div>  
  19.             <div class="editor-field">@Html.PasswordFor(u => u.Password)  
  20.                 @Html.ValidationMessageFor(u => u.Password)  
  21.             </div>  
  22.             <div class="editor-label">@Html.LabelFor(u => u.FirstName)</div>  
  23.             <div class="editor-field">@Html.TextBoxFor(u => u.FirstName)  
  24.                 @Html.ValidationMessageFor(u => u.FirstName)  
  25.             </div>  
  26.              <div class="editor-label">@Html.LabelFor(u => u.LastName)</div>  
  27.             <div class="editor-field">@Html.TextBoxFor(u => u.LastName)  
  28.                 @Html.ValidationMessageFor(u => u.LastName)  
  29.             </div>  
  30.    
  31.             <input type="submit" value="Register" />  
  32.         </fieldset>  
  33.     </div>  
  34. }  

LogOut.cshtml

  1. @{  
  2.     ViewBag.Title = "LogOut";  
  3.     Layout = "~/Views/Shared/_Layout.cshtml";  
  4. }  
  5.    
  6. <h2>LogOut</h2>  
  7.    
  8. public ActionResult LogOut()  
  9. {  
  10.     FormsAuthentication.SignOut();  
  11.     return RedirectToAction("Index""Home");  
  12. }  

Now hit F5 to run the application and click on the "Register" button and don't put anything in the TextBoxes and click the "Register" button.

img5.jpg

Image 5.

As you can see in the model class, all fields are required so these messages are displayed.

img6.jpg

Image 6.

Now if I put a password value less than 6 characters or more than 150 characters then this message will display:

img7.jpg

Image 7.

Now insert all values properly, then you will see it will register and data should inserted into the database, now you can login.

img8.jpg

Image 8.

img9.jpg

Image 9.

Conclusion

In this article we have learned the basic concepts of login using Entity Framework with Razor.