Multiple Models In One View Using ASP.NET MVC And Entity Framework

In a client requirement, I needed to create a page where two forms or models exist in a single View (page), like login and registration in the same single view.

Introduction
 
In a client requirement, I needed to create a page where two forms or models exist in a single view (page), like login and registration in the same single view.
 
Description
 
To fulfill this requirement, I used MVC with Entity Framework and SQL Server. For more details about MVC, go through my previous articles and blogs.
On the registration page, the user will register as new and on the login page, existing users will log in with their credentials. These two functionalities need to be implemented in the same view using MVC facility. The other script related part is added to show the message for successful or ivalid credentials during registration and login operations.
 
Source Code
Steps to be followed.
 
Step 1
 
Create a table named Users.
  1. CREATE TABLE [dbo].[Users](  
  2.     [UserID] [int] IDENTITY(1,1) NOT NULL,  
  3.     [Username] [varchar](50) NULL,  
  4.     [Password] [varchar](50) NULL,  
  5.     [FullName] [varchar](150) NULL,  
  6. PRIMARY KEY CLUSTERED   
  7. (  
  8.     [UserID] ASC  
  9. )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ONON [PRIMARY]  
  10. ON [PRIMARY]  
  11.   
  12. GO 
Step 2 - Add Entity Data Model
 
I have added entity data model named "Satyadatabasemodel.edmx" . After creating the Data model, we have to modify our generated entity (table) for applying the validation to the required fields. Here, we need to modify the User.cs file.
 
Code Ref
  1. namespace SatyaprakashMultimodels  
  2. {  
  3.     using System;  
  4.     using System.Collections.Generic;  
  5.     using System.ComponentModel.DataAnnotations;  
  6.     public partial class User  
  7.     {  
  8.         public int UserID { getset; }  
  9.         [Required]  
  10.         public string Username { getset; }  
  11.         [Required]  
  12.         [DataType(System.ComponentModel.DataAnnotations.DataType.Password)]  
  13.         public string Password { getset; }  
  14.         [Required]  
  15.         public string FullName { getset; }  
  16.     }  

Code Description
 
Here, all the fields are put with the required attribute for validation purposes.
 
Step 3
 
I need a ViewModel for getting the data as a single entity.  Here, I created a class file named "SignIn.cs" in the ViewModel folder.
 
Code Ref
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Threading.Tasks;  
  6. using System.ComponentModel.DataAnnotations;  
  7.   
  8. namespace SatyaprakashMultimodels.ViewModel  
  9. {  
  10.     public class SignIn  
  11.     {  
  12.         public User User { getset; }  
  13.         public Login Login { getset; }  
  14.     }  
  15.   
  16.     public class Login  
  17.     {  
  18.         [Required]  
  19.         public string UserName { getset; }  
  20.         [Required]  
  21.         [DataType(System.ComponentModel.DataAnnotations.DataType.Password)]  
  22.         public string Password { getset; }  
  23.     }  

Code Description
 
I used two classes, SignIn and Login, for new user registration and for logging the existing users in respectively.
 
Step 4
 
Then, I have added one controller action method named "LoginRegister" to the HomeController.cs file.
 
Code Ref
  1. using SatyaprakashMultimodels.ViewModel;  
  2. using System;  
  3. using System.Collections.Generic;  
  4. using System.Linq;  
  5. using System.Web;  
  6. using System.Web.Mvc;  
  7.   
  8. namespace SatyaprakashMultimodels.Controllers  
  9. {  
  10.     public class HomeController : Controller  
  11.     {  
  12.         public ActionResult Index()  
  13.         {  
  14.             return View();  
  15.         }  
  16.   
  17.         public ActionResult LoginRegister(SignIn lr)  
  18.         {  
  19.             return View(new SignIn { Login = new Login(), User = new User() });  
  20.   
  21.         }  
  22.   
  23.         [HttpPost]  
  24.         public ActionResult Login(SignIn l)  
  25.         {  
  26.             string message = "";  
  27.             if (ModelState.IsValid)  
  28.             {  
  29.                 using (CrystalGranite2016Entities1 dc = new CrystalGranite2016Entities1())  
  30.                 {  
  31.                     var v = dc.Users.Where(a => a.Username.Equals(l.Login.UserName) && a.Password.Equals(l.Login.Password)).FirstOrDefault();  
  32.                     if (v != null)  
  33.                     {  
  34.                         message = "Login Success";  
  35.                         return RedirectToAction("Success"new { message = message });  
  36.                     }  
  37.                     else  
  38.                     {  
  39.                         message = "login failed";  
  40.                     }  
  41.                 }  
  42.             }  
  43.             ViewBag.Message = message;  
  44.             return View("LoginRegister", l);  
  45.   
  46.         }  
  47.   
  48.         [HttpPost]  
  49.         public ActionResult Register(SignIn r)  
  50.         {  
  51.             string message = "";  
  52.             if (ModelState.IsValid)  
  53.             {  
  54.                 using (CrystalGranite2016Entities1 dc = new CrystalGranite2016Entities1())  
  55.                 {  
  56.                     var v = dc.Users.Where(a => a.Username.Equals(r.User.Username)).FirstOrDefault();  
  57.                     if (v == null)  
  58.                     {  
  59.                         dc.Users.Add(r.User);  
  60.                         dc.SaveChanges();  
  61.                         message = "Successfully Registered";  
  62.                         return RedirectToAction("Success"new { message = message });  
  63.                     }  
  64.                     else  
  65.                     {  
  66.                         message = "Username no available";  
  67.                     }  
  68.                 }  
  69.             }  
  70.             ViewBag.Message = message;  
  71.             return View("LoginRegister", r);  
  72.   
  73.         }  
  74.   
  75.         public ActionResult Success(string message)  
  76.         {  
  77.             ViewBag.Message = message;  
  78.             return View();  
  79.         }  
  80.   
  81.         public ActionResult About()  
  82.         {  
  83.             ViewBag.Message = "Your application description page.";  
  84.   
  85.             return View();  
  86.         }  
  87.   
  88.         public ActionResult Contact()  
  89.         {  
  90.             ViewBag.Message = "Your contact page.";  
  91.   
  92.             return View();  
  93.         }  
  94.     }  

Code Description
 
This Action method is used to render one view for both Login & New User Registration.
  1. public ActionResult LoginRegister(SignIn lr)  
  2.        {  
  3.            return View(new SignIn { Login = new Login(), User = new User() });  
  4.   
  5.        } 
Then, I added another controller action method named Login for existing login purposes and CrystalGranite2016Entities1 is the name of the Database entity class file. It will show a message to the end user informing them if the credentials are correct or not.
  1. [HttpPost]  
  2.        public ActionResult Login(SignIn l)  
  3.        {  
  4.            string message = "";  
  5.            if (ModelState.IsValid)  
  6.            {  
  7.                using (CrystalGranite2016Entities1 dc = new CrystalGranite2016Entities1())  
  8.                {  
  9.                    var v = dc.Users.Where(a => a.Username.Equals(l.Login.UserName) && a.Password.Equals(l.Login.Password)).FirstOrDefault();  
  10.                    if (v != null)  
  11.                    {  
  12.                        message = "Login Success";  
  13.                        return RedirectToAction("Success"new { message = message });  
  14.                    }  
  15.                    else  
  16.                    {  
  17.                        message = "login failed";  
  18.                    }  
  19.                }  
  20.            }  
  21.            ViewBag.Message = message;  
  22.            return View("LoginRegister", l);  
  23.   
  24.        } 
Like this, we have added another controller action method named "Register". It is used for new user registration entries and it will show a message based on the new user registration.
  1. public ActionResult Register(SignIn r)  
  2.         {  
  3.             string message = "";  
  4.             if (ModelState.IsValid)  
  5.             {  
  6.                 using (CrystalGranite2016Entities1 dc = new CrystalGranite2016Entities1())  
  7.                 {  
  8.                     var v = dc.Users.Where(a => a.Username.Equals(r.User.Username)).FirstOrDefault();  
  9.                     if (v == null)  
  10.                     {  
  11.                         dc.Users.Add(r.User);  
  12.                         dc.SaveChanges();  
  13.                         message = "Successfully Registered";  
  14.                         return RedirectToAction("Success"new { message = message });  
  15.                     }  
  16.                     else  
  17.                     {  
  18.                         message = "Username no available";  
  19.                     }  
  20.                 }  
  21.             }  
  22.             ViewBag.Message = message;  
  23.             return View("LoginRegister", r);  
  24.   
  25.         } 
I have created another controller action method named Success to manage different Success messages in the View.
  1. public ActionResult Success(string message)  
  2.        {  
  3.            ViewBag.Message = message;  
  4.            return View();  
  5.        } 
Step 5
 
Add a View named "LoginRegister.cshtml"  in Views >> Home Folder.
 
Code Ref
  1. @model SatyaprakashMultimodels.ViewModel.SignIn  
  2. @{  
  3.     ViewBag.Title = "User SignIn";  
  4.  }  
  5.   
  6. <h2>Login Register</h2><link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">  
  7. <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>  
  8. <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>  
  9.   
  10.   
  11. <script src="https://cdnjs.cloudflare.com/ajax/libs/bootbox.js/4.4.0/bootbox.min.js">  
  12.   
  13. </script>   
  14.   
  15. <script>  
  16. bootbox.alert({  
  17.         message: '@ViewBag.Message',  
  18.         size:'large'  
  19. });  
  20. </script>  
  21.   
  22. <div style="color:red">  
  23.     @ViewBag.Message  
  24. </div>  
  25. <style>    
  26.         table {    
  27.             font-family: arial, sans-serif;    
  28.             border-collapse: collapse;    
  29.             width: 100%;    
  30.         }    
  31.     
  32.         td, th {    
  33.             border: 1px solid #dddddd;    
  34.             text-align: left;    
  35.             padding: 8px;    
  36.         }    
  37.     
  38.         tr:nth-child(even) {    
  39.             background-color: #dddddd;    
  40.         }    
  41.     
  42.         .button {    
  43.             background-color: #4CAF50;    
  44.             border: none;    
  45.             color: white;    
  46.             padding: 15px 32px;    
  47.             text-align: center;    
  48.             text-decoration: none;    
  49.             display: inline-block;    
  50.             font-size: 16px;    
  51.             margin: 4px 2px;    
  52.             cursor: pointer;    
  53.         }    
  54.     
  55.         .button4 {    
  56.             border-radius: 9px;    
  57.         }    
  58.     
  59.         input[type=text], select {    
  60.             width: 60%;    
  61.             padding: 12px 20px;    
  62.             margin: 8px 0;    
  63.             display: inline-block;    
  64.             border: 1px solid #ccc;    
  65.             border-radius: 4px;    
  66.             box-sizing: border-box;    
  67.         }    
  68.         input[type=password], select {    
  69.             width: 60%;    
  70.             padding: 12px 20px;    
  71.             margin: 8px 0;    
  72.             display: inline-block;    
  73.             border: 1px solid #ccc;    
  74.             border-radius: 4px;    
  75.             box-sizing: border-box;    
  76.         }   
  77.     </style>    
  78. <table>  
  79.     <tr>  
  80.         <th style="background-color: Yellow;color: blue"><b>Existing User SignIn</b></th>  
  81.         <th style="background-color: Yellow;color: blue"><b>New User Register</b></th>  
  82.     </tr>  
  83.     <tr>  
  84.         <td>  
  85.             @using (Html.BeginForm("Login""Home", FormMethod.Post))  
  86.             {  
  87.                 <table>  
  88.                     <tr>  
  89.                         <td>Username : </td>  
  90.                         <td>@Html.TextBoxFor(a => a.Login.UserName)</td>  
  91.                     </tr>  
  92.                     <tr>  
  93.                         <td>Password : </td>  
  94.                         <td>@Html.EditorFor(a => a.Login.Password)</td>  
  95.                     </tr>  
  96.                     <tr>  
  97.                         <td></td>  
  98.                         <td> <input type="submit" class="button button4"  value="Go" /></td>  
  99.                     </tr>  
  100.                 </table>  
  101.             }  
  102.         </td>  
  103.         <td>  
  104.             @using (Html.BeginForm("Register""Home", FormMethod.Post))  
  105.             {  
  106.                 <table>  
  107.                     <tr>  
  108.                         <td>Fullname : </td>  
  109.                         <td>@Html.TextBoxFor(a => a.User.FullName)</td>  
  110.                     </tr>  
  111.                     <tr>  
  112.                         <td>Username : </td>  
  113.                         <td>@Html.TextBoxFor(a => a.User.Username)</td>  
  114.                     </tr>  
  115.                     <tr>  
  116.                         <td>Password : </td>  
  117.                         <td>@Html.EditorFor(a => a.User.Password)</td>  
  118.                     </tr>  
  119.                     <tr>  
  120.                         <td></td>  
  121.                         <td>  
  122.                             <input type="submit" class="button button4" value="Submit" />  
  123.                         </td>  
  124.                     </tr>  
  125.                 </table>  
  126.             }  
  127.         </td>  
  128.     </tr>  
  129. </table>  
  130.   
  131. @*@section Scripts {  
  132.     @Scripts.Render("~/bundles/jqueryval")  
  133. }*@  
  134.   
  135. <footer>  
  136.     <p style="background-color: Yellow; font-weight: bold; color:blue; text-align: center; font-style: oblique">© @DateTime.Now.ToLocalTime()</p> @*Add Date Time*@  
  137. </footer> 
Code Description
 
I have added one single view for both  Login and New User Registration. Inside BeginForm, we set the action tag to the specified controller and action for Login and Register action methods in Home Controller.
  1. @using (Html.BeginForm("Login""Home", FormMethod.Post))  
  2. {  
  3. }  
  4.   
  5. @using (Html.BeginForm("Register""Home", FormMethod.Post))  
  6. {  

I have added Bootbox JavaScript library and Div tag to show an error message to the end user.
 
Error Message displayed using Bootbox.
  1. <script>  
  2. bootbox.alert({  
  3.         message: '@ViewBag.Message',  
  4.         size:'large'  
  5. });  
  6. </script> 
Another Error Message displayed using Div tag.
  1. <div style="color:red">  
  2.     @ViewBag.Message  
  3. </div> 
Step-6
 
I have added another View named "Success.cshtml".
 
Code Ref
  1. @{  
  2.     ViewBag.Title = "Success";  
  3. }  
  4.   
  5. <h2>Message Confirmation....</h2>  
  6. <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">  
  7. <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>  
  8. <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>  
  9.   
  10.   
  11. <script src="https://cdnjs.cloudflare.com/ajax/libs/bootbox.js/4.4.0/bootbox.min.js">  
  12.   
  13. </script>    
  14.   
  15. <script>  
  16. bootbox.alert({  
  17.         message: '@ViewBag.Message',  
  18.         size:'large'  
  19. });  
  20. </script>  
  21.   
  22. <div style="color:green">  
  23.         @ViewBag.Message  
  24.     </div>  
  25.   
  26. <footer>  
  27.     <p style="background-color: Yellow; font-weight: bold; color:blue; text-align: center; font-style: oblique">© @DateTime.Now.ToLocalTime()</p> @*Add Date Time*@  
  28. </footer> 
Code Decription
 
This View shows up in case of successful user login and user registration only. I have added Bootbox JavaScript library and Div tag to show this success message to the end user.
  1. <script>  
  2. bootbox.alert({  
  3.         message: '@ViewBag.Message',  
  4.         size:'large'  
  5. });  
  6. </script>  
  7.   
  8. <div style="color:green">  
  9.         @ViewBag.Message  
  10. </div> 
Step-7
 
Check Web.Config for Database Connection String. Here, add name and nothing but the Autogenerate Database Entity class file name, i.e., "CrystalGranite2016Entities1".
  1. <connectionStrings>  
  2. <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\aspnet-SatyaprakashMultimodels-20171223092521.mdf;Initial Catalog=aspnet-SatyaprakashMultimodels-20171223092521;Integrated Security=True" providerName="System.Data.SqlClient" />
  3. <add name="CrystalGranite2016Entities1" connectionString="metadata=res://*/Satyadatabasemodel.csdl|res://*/Satyadatabasemodel.ssdl|res://*/Satyadatabasemodel.msl;provider=System.Data.SqlClient;provider connection string="data source=SODN-PAVILION\SQLEXPRESS;initial catalog=CrystalGranite2016;persist security info=True;user id=sa;password=satya;multipleactiveresultsets=True;application name=EntityFramework"" providerName="System.Data.EntityClient" />  
  4. </connectionStrings> 
Step-8
 
In RouteConfig File, I have added Controller name and Action method name for setting the start page.
  1. routes.MapRoute(  
  2.                 name: "Default",  
  3.                 url: "{controller}/{action}/{id}",  
  4.                 defaults: new { controller = "Home", action = "LoginRegister", id = UrlParameter.Optional }  
  5.             );  
OUTPUT
 
The URL is: http://localhost:2546/Home/LoginRegister
 

I created a new user as the below image. But already, a user in our database goes by the same username, Satya.
 
 
So, I tried different names Satyadev. After that, I got a successful message.
 
 
Try for the login part using Satyadev username.
 
 
Check In the database:
 
 
Mobile View
 
 
Summary
  • Use more than one model in one view.
  • MVC with Entity Frameork and Bootstrap.
  • Bootbox library for message display.