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 -

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.

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;

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. --Author : Suryakant
  3. --Created Date : 4-03-2017
  4. --Description : Creating Database
  5. --******************************************--
  6. --Create Datbase
  7. Create Database DemoWebAppDB
  8. Use DemoWebAppDB
  9. --Create Table
  10. CREATE TABLE [dbo].[tbl_RegisterUser] (
  11. [iId] INT IDENTITY (1, 1) NOT NULL,
  12. [sUserName] VARCHAR (50) NULL,
  13. [sEmail] VARCHAR (100) NULL,
  14. [sPassword] VARCHAR (20) NULL,
  15. [sPhoneNumber] VARCHAR (10) NULL,
  16. PRIMARY KEY CLUSTERED ([iId] ASC),
  17. 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]')
  18. );

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. [Bind(Exclude="iId")]
  9. public partial class tbl_RegisterUser
  10. {
  11. [ScaffoldColumn(false)]
  12. [Key]
  13. public int iId { get; set; }
  14. [Required(ErrorMessage="Please enter User Name !!!")]
  15. [Display(Name="User Name :")]
  16. [StringLength(30,ErrorMessage="User name must be thirty charter long.")]
  17. public string sUserName { get; set; }
  18. [Required(ErrorMessage="Pleae Enter Email Adress !!!")]
  19. [EmailAddress(ErrorMessage="Please Enter valid Email Id !!!")]
  20. [Display(Name="Email Adress :")]
  21. [DataType(DataType.EmailAddress)]
  22. public string sEmail { get; set; }
  23. [Required(ErrorMessage="Please Enter Password !!!")]
  24. [Display(Name="Password :")]
  25. [StringLength(9,ErrorMessage="Password must be nine character long.")]
  26. public string sPassword { get; set; }
  27. [NotMapped]
  28. [Required(ErrorMessage = "Please Enter Confirm Password !!!")]
  29. [Display(Name = "Confirm Password :")]
  30. [System.ComponentModel.DataAnnotations.Compare("sPassword",ErrorMessage="Confirm Password must match with Password !!!")]
  31. public string sCnfPassword { get; set; }
  32. [Required(ErrorMessage="Please Enter Phone Number !!!")]
  33. [Display(Name="Phone Number :")]
  34. [DataType(DataType.PhoneNumber)]
  35. [StringLength(10,ErrorMessage="Phone number must be 10 digit.",MinimumLength=10)]
  36. public string sPhoneNumber { get; set; }
  37. }
  38. }

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 .

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;

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

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 ;

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. <h2>Welcome To Login Page</h2>
  7. <html>
  8. <body>
  9. <div class="container">
  10. <div class="row">
  11. <div class="col-md-6 col-md-offset-3">
  12. <div class="panel panel-login">
  13. <div class="panel-heading">
  14. <div class="row">
  15. <div class="col-xs-6">
  16. <a href="#" class="active" id="login-form-link">Login</a>
  17. </div>
  18. <div class="col-xs-6">
  19. <a href="#" id="register-form-link">Register</a>
  20. </div>
  21. </div>
  22. <hr>
  23. </div>
  24. <div class="panel-body">
  25. <div class="row">
  26. <div class="col-lg-12">
  27. @using (Html.BeginForm("Index", "LoginDemo", FormMethod.Post, new { id = "login-form", style = "display:block" }))
  28. {
  29. @Html.AntiForgeryToken()
  30. <div class="form-group">
  31. @Html.TextBoxFor(m => m.sUserName, new { @class = "form-control", id = "UserName", placeholder = "Enter User Name/EmailId", tabindex = "1" })
  32. @Html.ValidationMessageFor(m => m.sUserName)
  33. </div>
  34. <div class="form-group">
  35. @Html.PasswordFor(m => m.sPassword, new { @class = "form-control", id = "password", placeholder = "Enter Password", tabindex = "2" })
  36. @Html.ValidationMessageFor(m => m.sPassword)
  37. </div>
  38. <div class="form-group col-lg-offset-4">
  39. <input type="checkbox" tabindex="3" class="" name="remember" id="remember">
  40. <label for="remember"> Remember Me</label>
  41. </div>
  42. <div class="form-group">
  43. <div class="row">
  44. <div class="col-sm-4 col-lg-offset-3">
  45. <input type="submit" name="command" id="login-submit" tabindex="4" class="form-control btn btn-default" value="Log In">
  46. </div>
  47. </div>
  48. </div>
  49. <div class="form-group">
  50. <div class="row">
  51. <div class="col-lg-12" style="margin-left:30%">
  52. <a href="#" tabindex="5" class="forgot-password">Forgot Password?</a>
  53. </div>
  54. </div>
  55. </div>
  56. @Html.ValidationSummary("");
  57. }
  58. @using (Ajax .BeginForm("Register", "LoginDemo", new AjaxOptions { OnSuccess = "RegisterSuccess", HttpMethod = "POST", UpdateTargetId = "Message" }, new { id = "register-form", style = "display:none" }))
  59. {
  60. @Html.AntiForgeryToken()
  61. @Html.ValidationSummary(true, "", new { @class = "text-danger" })
  62. @Html.Partial("_RegisterPage")
  63. }
  64. </div>
  65. </div>
  66. <label style="color:green" id="Message"></label>
  67. </div>
  68. </div>
  69. </div>
  70. </div>
  71. </div>
  72. </body>
  73. </html>
  74. <script>
  75. $(function () {
  76. debugger;
  77. $("#register-form-link").click(function () {
  78. debugger;
  79. $("#register-form").css('display', 'block');
  80. $("#login-form").css('display', 'none');
  81. $("#register-form-link").addClass('active');
  82. $("#login-form-link").removeClass('active');
  83. $(".field-validation-error").css('display', "none");
  84. $(".input-validation-error").css("border", "1px solid #cccccc");
  85. });
  86. $("#login-form-link").click(function () {
  87. $("#register-form").css('display', 'none');
  88. $("#login-form").css('display', 'block');
  89. $("#register-form-link").removeClass('active');
  90. $("#login-form-link").addClass('active');
  91. $("#Message").hide();
  92. });
  93. });
  94. function RegisterSuccess(data) {
  95. debugger;
  96. if (data!="") {
  97. for (var i = 0; i < data.keys.length; i++) {
  98. if (data.ErrorMessage[i]!="") {
  99. document.getElementById(data.keys[i]).nextElementSibling.style.display = "block";
  100. document.getElementById(data.keys[i]).nextElementSibling.textContent = data.ErrorMessage[i];
  101. document.getElementById(data.keys[i]).nextElementSibling.className = "field-validation-error" //field-validation-valid
  102. }
  103. else
  104. {
  105. document.getElementById(data.keys[i]).nextElementSibling.style.display = "none";
  106. }
  107. }
  108. }
  109. else
  110. {
  111. $("#Message").text("Registration successful !!!");
  112. }
  113. }
  114. </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. <div class="form-group">
  3. @Html.TextBoxFor(m => m.sUserName, new { @class = "form-control", id = "sUserName", placeholder = "Enter User Name", tabindex = "1" })
  4. @Html.ValidationMessageFor(m => m.sUserName)
  5. </div>
  6. <div class="form-group">
  7. @Html.TextBoxFor(m => m.sEmail, new { @class = "form-control", id = "sEmail", placeholder = "Email Address", tabindex = "2" })
  8. @Html.ValidationMessageFor(m => m.sEmail)
  9. </div>
  10. <div class="form-group">
  11. @Html.PasswordFor(m => m.sPassword, new { @class = "form-control", id = "sPassword", placeholder = "Password", tabindex = "3" })
  12. @Html.ValidationMessageFor(m => m.sPassword)
  13. </div>
  14. <div class="form-group">
  15. @Html.PasswordFor(m => m.sCnfPassword, new { @class = "form-control", id = "sCnfPassword", placeholder = "Confirm Password", tabindex = "4" })
  16. @Html.ValidationMessageFor(m => m.sCnfPassword)
  17. </div>
  18. <div class="form-group">
  19. @Html.TextBoxFor(m => m.sPhoneNumber, new { @class = "form-control", id = "sPhoneNumber", placeholder = "Enter Phone Number", tabindex = "5" })
  20. @Html.ValidationMessageFor(m => m.sPhoneNumber)
  21. </div>
  22. <div class="form-group">
  23. <div class="row">
  24. <div class="col-sm-4">
  25. <input type="submit" name="register-submit" id="register-submit" tabindex="5" class="form-control btn btn-default" value="Register Now">
  26. </div>
  27. </div>
  28. </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. .navbar-brand {
  19. color: white !important;
  20. }
  21. </style>
  22. </head>
  23. <body>
  24. <div class="navbar navbar-inverse navbar-fixed-top" style="background-image:linear-gradient(#54b4eb, #2fa4e7 60%, #1d9ce5)">
  25. <div class="container">
  26. <div class="navbar-header">
  27. <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
  28. <span class="icon-bar"></span>
  29. <span class="icon-bar"></span>
  30. <span class="icon-bar"></span>
  31. </button>
  32. @Html.ActionLink("Demo Login App", "Index", "Home", null, new { @class = "navbar-brand" })
  33. </div>
  34. </div>
  35. </div>
  36. <div class="container body-content">
  37. @RenderBody()
  38. <hr />
  39. <footer>
  40. <p>© @DateTime.Now.Year - My ASP.NET Application</p>
  41. </footer>
  42. </div>
  43. @RenderSection("scripts", required: false)
  44. </body>
  45. </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. <h2>Home</h2>
  5. <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.