Understanding Model Binding With Database First Approach Using Login App From Scratch

Introduction

In this article, I am going to explain to you about model validation using data annotation property with model binding from scratch. Here, I am going to use Entity Framework database first approach to do all operations for login app.

If you are a beginner or new to MVC, I must recommend you please read the article; it will be worth your time.

What we are going to learn -
  • Understanding Model validation in MVC
  • Different data annotation property in MVC
  • Understanding of Entity frameworkd atabase first approach.
  • Understanding model and binding to view.
  • Understanding each data annotation property.
  • Login app validating using model and using entity frame work register new user.

Before we start, download the complete project from here.

To begin with, unzip the zipped file, open the Solution using Visual Studio. After completely loading the project inside VS, first thing you need to do is to open web.config.cs file and change the connection string as follows.

  1. <add name="SuryaTechDBEntities" connectionString="metadata=res://*/Models.LoginDemo.csdl|res://*/Models.LoginDemo.ssdl|res://*/Models.LoginDemo.msl;provider=System.Data.SqlClient;provider connection string="data source=OMM-PC;initial catalog=SuryaTechDB;user id=sa;password=123;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />   

From above, you need to change the following things.

  • Data source name with your Sql server data source name.
  • Initial catalog field.
  • User id and Password field.

After that, run this below SQL Query to create new database. 

  1. CREATE TABLE [dbo].[tbl_RegisterUser] (   
  2.     [iId]          INT           IDENTITY (1, 1) NOT NULL,   
  3.     [sUserName]    VARCHAR (50)  NULL,   
  4.     [sEmail]       VARCHAR (100) NULL,   
  5.     [sPassword]    VARCHAR (20)  NULL,   
  6.     [sPhoneNumber] VARCHAR (10)  NULL,   
  7.     PRIMARY KEY CLUSTERED ([iId] ASC),   
  8.     CONSTRAINT [CK_PhoneNumber] CHECK ([sPhoneNumber] like '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]')   
  9. );    

Let’s begin.

Background

Model validation in MVC

Before proceeding to talk about model validation, let me first tell you what is a model. In simple terms, model is a class which provides input to the View.

Model validation is directly indicating that we are going to validate all the data members of that particular model/class.

In ASP.NET MVC, we can achieve this by using data-annotation attributes.

Now, we need to understand what data-annotation attributes are.

Data-annotation attributes are the predefined class through which we can validate model class. These data-annotation classes are present under System.ComponentModel.DataAnnotations namespace.

The purpose of validating model is; as I said above, that model provides input to the view so before doing any action using model our first goal is to check whether the data is correct or not.

Inside model we defined different properties which can bind through view. Before binding the property to view we first need to check whether the data is correct or not.

This can be done in two ways;

  • You can check all the input data manually using java script.
  • You can use model binding.

In our discussion, I will tell you about the second approach. Let’s understand this with a demo.

In this demo, am going to create a simple login app using database first approach.

Database Part

Run the bellow SQL query.

  1. --******************************************--  
  2.   
  3. --Author              : Suryakant  
  4. --Created Date        : 4-03-2017  
  5. --Description         : Creating Database  
  6.   
  7. --******************************************--  
  8.   
  9. --Create Datbase  
  10.   
  11. Create Database DemoWebAppDB  
  12.   
  13. Use DemoWebAppDB  
  14.   
  15. --Create Table  
  16.   
  17. CREATE TABLE [dbo].[tbl_RegisterUser] (   
  18.     [iId]          INT           IDENTITY (1, 1) NOT NULL,   
  19.     [sUserName]    VARCHAR (50)  NULL,   
  20.     [sEmail]       VARCHAR (100) NULL,   
  21.     [sPassword]    VARCHAR (20)  NULL,   
  22.     [sPhoneNumber] VARCHAR (10)  NULL,   
  23.     PRIMARY KEY CLUSTERED ([iId] ASC),   
  24.     CONSTRAINT [CK_PhoneNumber] CHECK ([sPhoneNumber] like '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]')   
  25. );    

Let’s jump to Visual Studio and start creating new project.

Step 1

Click on New Project from the File menu.

ASP.NET

ASP.NET

We have created a project successfully.

Step-2

In this step, we are going to add ADO.NET Entity. Here, we are using database first approach. Before going to create Entity Model, let me first tell you what database first approach is.

Database first approach is a process through which Visual Studio can generate models by using database table.

Learn more details about this from here.

Remember, here in entity framework, all tables are treated as Classes and all columns of the table treated as properties.

Let’s proceed to step-2 and add ASO.NET Entity data model.

ASP.NET

ASP.NET

ASP.NET

ASP.NET

ASP.NET

Now, click on Finish button.

Now, you get pictorial representation of our table as below.

ASP.NET

Now, click on the Solution Explorer and see the new file called edmx file is added under Models folder.

ASP.NET

Now, we have successfully created Model class for our application, that is tbl_RegsisterUser.cs class.

With this Model class, we have one important class called ad LoginDemo.Context.cs class.

This class plays an important roles while working with database operations.

Step 3

In this step we are going to add data-annotation property to our tbl_RegisterUser.cs class.

Add the below code,

  1. namespace DemoLoginApp.Models  
  2. {  
  3.     using System;  
  4.     using System.Collections.Generic;  
  5.     using System.ComponentModel.DataAnnotations;  
  6.     using System.ComponentModel.DataAnnotations.Schema; //Not Mapped  
  7.     using System.Web.Mvc;  
  8.       
  9.     [Bind(Exclude="iId")]  
  10.     public partial class tbl_RegisterUser  
  11.     {  
  12.        [ScaffoldColumn(false)]  
  13.         [Key]  
  14.         public int iId { get; set; }  
  15.   
  16.         [Required(ErrorMessage="Please enter User Name !!!")]  
  17.        [Display(Name="User Name :")]  
  18.         [StringLength(30,ErrorMessage="User name must be thirty charter long.")]  
  19.         public string sUserName { get; set; }  
  20.   
  21.         [Required(ErrorMessage="Pleae Enter Email Adress !!!")]  
  22.         [EmailAddress(ErrorMessage="Please Enter valid Email Id !!!")]  
  23.         [Display(Name="Email Adress :")]  
  24.         [DataType(DataType.EmailAddress)]  
  25.         public string sEmail { get; set; }  
  26.   
  27.         [Required(ErrorMessage="Please Enter Password !!!")]  
  28.         [Display(Name="Password :")]  
  29.         [StringLength(9,ErrorMessage="Password must be nine character long.")]  
  30.         public string sPassword { get; set; }  
  31.   
  32.         [NotMapped]  
  33.         [Required(ErrorMessage = "Please Enter Confirm Password !!!")]  
  34.         [Display(Name = "Confirm Password :")]  
  35.         [System.ComponentModel.DataAnnotations.Compare("sPassword",ErrorMessage="Confirm Password must match with Password !!!")]  
  36.         public string sCnfPassword { get; set; }  
  37.   
  38.         [Required(ErrorMessage="Please Enter Phone Number !!!")]  
  39.         [Display(Name="Phone Number :")]  
  40.         [DataType(DataType.PhoneNumber)]  
  41.         [StringLength(10,ErrorMessage="Phone number must be 10 digit.",MinimumLength=10)]  
  42.         public string sPhoneNumber { get; set; }  
  43.     }  
  44. }   

In the above class we saw that the property has been represented by data annotation attributes.

Let’s talk about some important concepts behind data annotation attributes;

In MVC all the data annotation attributes are present under “System.ComponentModel.DataAnnotations”.

Why Use This?

The purpose of using Data annotation attribute is validating model in server through Model State property of ModelStateDictionary Class.

Model State

This property plays an important role while doing model validation using data annotation property. ModelStateDictionary class contains the following important property and method which helps us validate the model .

  • Count
    It counts all the key value pairs present .Returns integer value.

  • IsValid
    This property tells whether the ModelState has an error or not; if no error exist sinside ModelState then it returns true other wise it returns false.

  • Clear()
    It help us to clear the state of model. It means it will clear all the errors present inside the model.

  • Values
    This property holds all the errors which comes from data annotation attributes.ModelStae.Values is type of ModelState list. In side ModelState class it contains a property called Errors and Values.

So by using ModelState.Values we can access all the errors present inside our model; we will see this later in our code.

Let’s understand how model binding works;

We always directly pass the model to view and access the model by directly using model property. That model property is defind under ViewDataDictionary class. The ViewDataDictionary class has a property called as View data; so by using ViewData property we can access the model property.

We can also accesss other important property of model from ViewDataDictionary class; some of the important properties of model are;

  • Model State
  • Model Meta Data
  • SetModel(object value) //Method.

Let’s proceed to our demo Login App;

We already created data-context class using database first approach; and we customized our data context class using various data-annotation attributes.

Let’s add a controller,

ASP.NET

Click on add;

ASP.NET

Next click on Add.

ASP.NET

Give the controller name as Login Demo.

After creation of controller add the bellow code inside LoginDemo controller. 

  1. using DemoLoginApp.Models;  
  2. using System;  
  3. using System.Collections.Generic;  
  4. using System.Linq;  
  5. using System.Web;  
  6. using System.Web.Mvc;  
  7.   
  8. namespace DemoLoginApp.Controllers  
  9. {  
  10.     public class LoginDemoController : Controller  
  11.     {  
  12.   
  13.         SuryaTechDBEntities _dbEntites = new SuryaTechDBEntities();  
  14.         // GET: /LoginDemo/  
  15.         public ActionResult Index()  
  16.           
  17.         {  
  18.             return View();  
  19.         }  
  20.         [HttpPost]  
  21.           
  22.         public ActionResult Index([Bind(Exclude="iId")]tbl_RegisterUser model)  
  23.         {  
  24.             var type = Request.RequestType;  
  25.             if (ModelState.Values.ToArray()[0].Errors.Count==0 && ModelState.Values.ToArray()[1].Errors.Count==0)  
  26.             {  
  27.                 if (CheckUser(model.sUserName,model.sPassword))  
  28.                 {  
  29.                     return RedirectToAction("Home"new { username=model.sUserName});  
  30.                 }  
  31.                 else  
  32.                 {  
  33.                      
  34.                     ModelState.Clear();  
  35.                     ModelState.AddModelError("""User Id or Password not exist; try again !!!");  
  36.                     return View(model);  
  37.                 }  
  38.                  
  39.             }  
  40.             else  
  41.             {  
  42.                 return View(model);  
  43.             }  
  44.               
  45.         }  
  46.   
  47.         private bool CheckUser(string UserId, string Password)  
  48.         {  
  49.             var User = _dbEntites.tbl_RegisterUser.FirstOrDefault(m => m.sUserName == UserId);  
  50.             if (User!=null)  
  51.             {  
  52.                 if (User.sPassword == Password)  
  53.                 {  
  54.                     return true;  
  55.                 }  
  56.                 else  
  57.                     return false;  
  58.             }  
  59.             else  
  60.             {  
  61.                 return false;  
  62.             }  
  63.         }  
  64.         [HttpPost]  
  65.         public ActionResult Register(tbl_RegisterUser model)  
  66.          {  
  67.             List<string> errorMessage = new List<string>();  
  68.             if (ModelState.IsValid)  
  69.             {  
  70.                 _dbEntites.tbl_RegisterUser.Add(model);  
  71.                 _dbEntites.SaveChanges();  
  72.                 return Json("", JsonRequestBehavior.AllowGet);  
  73.             }  
  74.             else  
  75.             {  
  76.                 for (int i = 0; i < ModelState.Values.Count; i++)  
  77.                 {  
  78.                     if (ModelState.Values.ToArray()[i].Errors.Count>0)  
  79.                     {  
  80.                         errorMessage.Add(ModelState.Values.ToArray()[i].Errors[0].ErrorMessage);  
  81.                     }  
  82.                     else  
  83.                     {  
  84.                         errorMessage.Add("");  
  85.                     }  
  86.                 }  
  87.   
  88.                 return Json(new {keys= ModelState.Keys,ErrorMessage=errorMessage }, JsonRequestBehavior.AllowGet);  
  89.             }  
  90.         }  
  91.          
  92.         public ActionResult Home(string username)  
  93.          {  
  94.             ViewData.Model = username;  
  95.             return View();  
  96.         }  
  97.         public ActionResult Logout()  
  98.         {  
  99.             return RedirectToAction("Index");  
  100.         }  
  101.     }  
  102. }   

Let’s talk about our LoginDemo Controller which we defined above;

The purpose of this controller is to create the Login page as well as Register page with full functionally for both login and register using entity framework.

So in this above controller class ;

  • Index Action Method represents both Login View and Register view.
  • In this example I have taken Register view page as partial view and rendering this inside index view.
  • CheckUser method is used to check whether the user exit or not.
  • Register method is used to register the user.

Let’s create the view page for Index action method.

ASP.NET

Add the index view page by right click on index action method.

After that add the below code inside index View; 

  1. @model DemoLoginApp.Models.tbl_RegisterUser  
  2. @{  
  3.     ViewBag.Title = "Index";  
  4.     var model = Model;  
  5. }  
  6.   
  7. <h2>Welcome To Login Page</h2>  
  8.   
  9. <html>  
  10. <body>  
  11.     <div class="container">  
  12.         <div class="row">  
  13.             <div class="col-md-6 col-md-offset-3">  
  14.                 <div class="panel panel-login">  
  15.                     <div class="panel-heading">  
  16.                         <div class="row">  
  17.                             <div class="col-xs-6">  
  18.                                 <a href="#" class="active" id="login-form-link">Login</a>  
  19.                             </div>  
  20.                             <div class="col-xs-6">  
  21.                                 <a href="#" id="register-form-link">Register</a>  
  22.                             </div>  
  23.                         </div>  
  24.                         <hr>  
  25.                     </div>  
  26.                     <div class="panel-body">  
  27.                         <div class="row">  
  28.                             <div class="col-lg-12">  
  29.   
  30.                                 @using (Html.BeginForm("Index""LoginDemo", FormMethod.Post, new { id = "login-form", style = "display:block" }))  
  31.                                 {  
  32.                                     
  33.                                     @Html.AntiForgeryToken()  
  34.                                     <div class="form-group">  
  35.                                         @Html.TextBoxFor(m => m.sUserName, new { @class = "form-control", id = "UserName", placeholder = "Enter User Name/EmailId", tabindex = "1" })  
  36.                                         @Html.ValidationMessageFor(m => m.sUserName)  
  37.                                     </div>  
  38.                                     <div class="form-group">  
  39.   
  40.                                         @Html.PasswordFor(m => m.sPassword, new { @class = "form-control", id = "password", placeholder = "Enter Password", tabindex = "2" })  
  41.                                         @Html.ValidationMessageFor(m => m.sPassword)  
  42.                                     </div>  
  43.                                     <div class="form-group col-lg-offset-4">  
  44.                                         <input type="checkbox" tabindex="3" class="" name="remember" id="remember">  
  45.                                         <label for="remember"> Remember Me</label>  
  46.                                     </div>  
  47.                                     <div class="form-group">  
  48.                                         <div class="row">  
  49.                                             <div class="col-sm-4 col-lg-offset-3">  
  50.                                                 <input type="submit" name="command" id="login-submit" tabindex="4" class="form-control btn btn-default" value="Log In">  
  51.                                             </div>  
  52.                                         </div>  
  53.                                     </div>  
  54.                                     <div class="form-group">  
  55.                                         <div class="row">  
  56.                                             <div class="col-lg-12" style="margin-left:30%">  
  57.                                                     <a href="#" tabindex="5" class="forgot-password">Forgot Password?</a>  
  58.                                             </div>  
  59.                                         </div>  
  60.                                     </div>  
  61.                                     @Html.ValidationSummary("");  
  62.                                 }  
  63.                                 @using (Ajax .BeginForm("Register""LoginDemo"new AjaxOptions { OnSuccess = "RegisterSuccess", HttpMethod = "POST", UpdateTargetId = "Message" }, new { id = "register-form", style = "display:none" }))  
  64.                                 {  
  65.                                     @Html.AntiForgeryToken()  
  66.                                     @Html.ValidationSummary(true""new { @class = "text-danger" })  
  67.   
  68.                                     @Html.Partial("_RegisterPage")  
  69.   
  70.                                 }  
  71.                             </div>  
  72.                         </div>  
  73.                         <label style="color:green" id="Message"></label>  
  74.   
  75.                     </div>  
  76.                 </div>  
  77.             </div>  
  78.         </div>  
  79.     </div>  
  80.   
  81. </body>  
  82. </html>  
  83. <script>  
  84.     
  85.     $(function () {  
  86.         debugger;  
  87.         $("#register-form-link").click(function () {  
  88.             debugger;  
  89.             $("#register-form").css('display''block');  
  90.             $("#login-form").css('display''none');  
  91.             $("#register-form-link").addClass('active');  
  92.             $("#login-form-link").removeClass('active');  
  93.             $(".field-validation-error").css('display'"none");  
  94.             $(".input-validation-error").css("border""1px solid #cccccc");  
  95.         });  
  96.         $("#login-form-link").click(function () {  
  97.             $("#register-form").css('display''none');  
  98.             $("#login-form").css('display''block');  
  99.             $("#register-form-link").removeClass('active');  
  100.             $("#login-form-link").addClass('active');  
  101.             $("#Message").hide();  
  102.         });  
  103.     });  
  104.     function RegisterSuccess(data) {  
  105.         debugger;  
  106.         if (data!="") {  
  107.             for (var i = 0; i < data.keys.length; i++) {  
  108.                 if (data.ErrorMessage[i]!="") {  
  109.                     document.getElementById(data.keys[i]).nextElementSibling.style.display = "block";  
  110.                     document.getElementById(data.keys[i]).nextElementSibling.textContent = data.ErrorMessage[i];  
  111.                     document.getElementById(data.keys[i]).nextElementSibling.className = "field-validation-error" //field-validation-valid  
  112.                 }  
  113.                 else  
  114.                 {  
  115.                     document.getElementById(data.keys[i]).nextElementSibling.style.display = "none";  
  116.                 }  
  117.             }  
  118.              
  119.         }  
  120.         else  
  121.         {  
  122.             $("#Message").text("Registration successful !!!");  
  123.         }  
  124.          
  125.     }  
  126. </script>   

After adding this let’s create our partial _Register.cshtml page.

Right click on LoginDemo folder then add partial page;

ASP.NET

Give the name as _RegisterPage.

Add the below code inside Register.cshtml; 

  1. @model DemoLoginApp.Models.tbl_RegisterUser  
  2.   
  3. <div class="form-group">  
  4.     @Html.TextBoxFor(m => m.sUserName, new { @class = "form-control", id = "sUserName", placeholder = "Enter User Name", tabindex = "1" })  
  5.     @Html.ValidationMessageFor(m => m.sUserName)  
  6. </div>  
  7. <div class="form-group">  
  8.     @Html.TextBoxFor(m => m.sEmail, new { @class = "form-control", id = "sEmail", placeholder = "Email Address", tabindex = "2" })  
  9.     @Html.ValidationMessageFor(m => m.sEmail)  
  10. </div>  
  11. <div class="form-group">  
  12.     @Html.PasswordFor(m => m.sPassword, new { @class = "form-control", id = "sPassword", placeholder = "Password", tabindex = "3" })  
  13.     @Html.ValidationMessageFor(m => m.sPassword)  
  14. </div>  
  15. <div class="form-group">  
  16.     @Html.PasswordFor(m => m.sCnfPassword, new { @class = "form-control", id = "sCnfPassword", placeholder = "Confirm Password", tabindex = "4" })  
  17.     @Html.ValidationMessageFor(m => m.sCnfPassword)  
  18. </div>  
  19. <div class="form-group">  
  20.     @Html.TextBoxFor(m => m.sPhoneNumber, new { @class = "form-control", id = "sPhoneNumber", placeholder = "Enter Phone Number", tabindex = "5" })  
  21.     @Html.ValidationMessageFor(m => m.sPhoneNumber)  
  22. </div>  
  23. <div class="form-group">  
  24.     <div class="row">  
  25.         <div class="col-sm-4">  
  26.             <input type="submit" name="register-submit" id="register-submit" tabindex="5" class="form-control btn btn-default" value="Register Now">  
  27.         </div>  
  28.     </div>  
  29. </div>   

After this replace _Layout.cshtml page by using the below code;

You can find the layout page inside view folder see below;

ASP.NET

Replace the _Layout.cshtml page code, 

  1. <!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4.     <meta charset="utf-8" />  
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">  
  6.     <title>@ViewBag.Title - My ASP.NET Application</title>  
  7.     <script src="~/Scripts/jquery-1.10.2.js"></script>  
  8.     @Styles.Render("~/Content/css")  
  9.     @Scripts.Render("~/bundles/modernizr")  
  10.     @Scripts.Render("~/bundles/jquery")  
  11.     @Scripts.Render("~/bundles/bootstrap")  
  12.     <script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>  
  13.     <style>  
  14.         .active {  
  15.             font-weight: bold;  
  16.             text-decoration: underline;  
  17.         }  
  18.   
  19.         .navbar-brand {  
  20.             color: white !important;  
  21.         }  
  22.     </style>  
  23. </head>  
  24. <body>  
  25.     <div class="navbar navbar-inverse navbar-fixed-top" style="background-image:linear-gradient(#54b4eb, #2fa4e7 60%, #1d9ce5)">  
  26.         <div class="container">  
  27.             <div class="navbar-header">  
  28.                 <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">  
  29.                     <span class="icon-bar"></span>  
  30.                     <span class="icon-bar"></span>  
  31.                     <span class="icon-bar"></span>  
  32.                 </button>  
  33.                 @Html.ActionLink("Demo Login App""Index""Home"nullnew { @class = "navbar-brand" })  
  34.   
  35.             </div>  
  36.             
  37.         </div>  
  38.     </div>  
  39.     <div class="container body-content">  
  40.         @RenderBody()  
  41.         <hr />  
  42.         <footer>  
  43.             <p>© @DateTime.Now.Year - My ASP.NET Application</p>  
  44.         </footer>  
  45.     </div>  
  46.   
  47.   
  48.     @RenderSection("scripts", required: false)  
  49. </body>  
  50. </html>   

Now add Home page which you will get after successful l login.

We already have a Home Action method inside our controller class.

Navigate to that action method and right click and add the Home page.

After that replace the below code of Home page; 

  1. @{  
  2.     ViewBag.Title = "Home";  
  3. }  
  4.   
  5. <h2>Home</h2>  
  6. <h3>Welcome @Model</h3>   

Now run your application and you get login page.

ASP.NET

Click on register tab you get Register page;

ASP.NET

Now register a user by providing details.

Give some wrong information you can get the model error message as shown below;
ASP.NET

If you successfully register a user and login through that user then you get anwelcome message as below;

Here my UserId:- Surya and Password:- 1234.

Let’s login;

ASP.NET

After login you get an welcome page showing as below:-

ASP.NET

You have successfully logged in. Cheers!!! J

Conclusion

In this Demo login app, we saw various data annotation attributes with model validations. So far, we discussed database first approach with inserting record and authenticating user.

Hope the above demo gives you a clear idea how to work with data base first approach with pure model validation. In this demo you can not find any single line of JavaScript code for checking the validation  -- I did all the validation by using model . Try this demo once; hope you definitely learn something new.

If anything is not working for you or if you  found mistakes then please let me know. 

That’s all; please share your valuable feedback about this article.

Thanks and happy Coding.