Understanding Form Validation Validation Using Dataannotations in Mvc5 Custom Validations Using Data Annotation Fetching Data From Database

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 19

Web Engineering (CS-666/CS-723)

Mr. Aftab Khan Email id: aftab@biit.edu.pk WhatsApp# 0344-8184704


Mr. Amir Rashid Email id: amir@biit.edu.pk, WhatsApp# 0302-5698539

(Week 7) Lecture 13-14


Objectives: Learning objectives of this lecture are

 Understanding Form Validation


 Validation using DataAnnotations in MVC5
 Custom Validations using Data Annotation
 Fetching Data From Database
Text Book & Resources: Professional ASP.NET MVC 5 by Jon Galloway, Brad Wilson, K. Scott Allen,
David Matson

Video Links:
https://www.youtube.com/watch?v=NrKyURTs45Y&list=PLjVp2I_4DPy_4CvU-
mdB_vfHfT8k7o18N&index=11&t=1270s

https://www.youtube.com/watch?v=98woEi4mPOs&list=PLjVp2I_4DPy_4CvU-
mdB_vfHfT8k7o18N&index=12&t=29s

https://www.youtube.com/watch?v=RJpFTkKHiBA&list=PLjVp2I_4DPy_4CvU-
mdB_vfHfT8k7o18N&index=13&t=45s

https://www.youtube.com/watch?v=LorEsTcvzqE&list=PLjVp2I_4DPy_4CvU-
mdB_vfHfT8k7o18N&index=14&t=663s

Form Validation and DataAnnotations in MVC5


Validation is an important feature in ASP.NET MVC applications. It is used to verify whether
the submitted data is valid or not. ASP.NET MVC provides a set of built-in validation that is
easy-to-use and at the same time, it is also a powerful way to check for errors and, if
necessary, display messages to the user.ASP.NET MVC uses DataAnnotations attributes to
implement validations. DataAnnotations includes built-in validation attributes for different
rules of validation, which can be easily applied to the properties of model class. ASP.NET
MVC framework will automatically ensure these rules and show validation messages in the
front end (view).
These DataAnnotations attributes are part of System.ComponentModel.DataAnnotations
namespace. In the following table, I have listed some DataAnnotations validation attributes.
Attribute Description
Required Specifies that field cannot be empty
StringLength Specifies the maximum length for text field
Range Defines a maximum and minimum limit of a
numeric field
RegularExpression Defines that the field value must follow the
rules within given Regular Expression
EmailAddress Specifies the format of email address
MaxLength Defines maximum length for text field
MinLength Defines minimum length for text field
You must know that client side validation (using java script) is not the solution of all
problems. Sometime you have to validate this on server side too. You want to apply
validation on the server side because you can protect against the hacker, who can simply
bypass your client side JavaScript and submit unsafe data to the server.

Custom Validation using DataAnnotations in MVC5


In some cases built in attributes are not enough to serve the purpose of validating all input data.
In such cases we have to write custom attribute. In the following section I have also explained
how to perform custom validations in asp.net mvc. I have applied custom validation on HireDate
attribute of Employee Model class.
Let us understand the concept of data validation with the help of example.

First of all create a class in Model Folder with name Employee. Here is the code for
Employee class.

using MVCDemo.CustomValidation;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace MVCDemo.Models
{
public class Employee
{
public int EmployeeID { get; set; }
[Required]
public string FirstName { get; set; }
public string LastName { get; set; }
[Required]
public string Gender { get; set; }
[Required]
[EmailAddress]
public string EmailAddress { get; set; }
public string City { get; set; }

[Range(25000, 500000, ErrorMessage = "Please enter correct


value")]
[Required]
/* We can control the display of data in a View (UI) using
display attributes */

[Display(Name ="Salary")]
public int Salary { get; set; }

[Range(20, 60, ErrorMessage = "Age must be between 20 and


60")]
[Required]
[Display(Name = "Age")]
public int Age { get; set; }

[Required]
[Display(Name = "Education Level")]
public int EducationLevel { get; set; }

[Required(ErrorMessage = "Please enter hire date")]


[Display(Name = "Hire Date")]
[CustomHireDate(ErrorMessage = "Hire Date must be less than or
equal to Today's Date")]
[DataType(DataType.Date)]
public DateTime? HireData { get; set; }

public Department Department { get; set; }

}
}

In the employee model class we have decorated different properties with attributes. Some have
one annotation as FirstName is required only. While some has multiple attributes such as age is
required and range must be between 20 and 60.
Pay special attention to highlight attribute CustomHireDate. It is user defined attribute to
perform custom validation. We have to make sure that Date must not greater than today using
this attribute. To create this custom attribute for HireDate follow these steps.

Create a folder CustomValidation in the Project. Add a class CustomHireDate in this


folder.The code for the class is given below.

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace MVCDemo.CustomValidation
{
public class CustomHireDate : ValidationAttribute
{
public override bool IsValid(object value)
{
DateTime dateTime = Convert.ToDateTime(value);

// if date is greater than current date return false


return dateTime <= DateTime.Now;//it will be true or false
}
}
}

Read the above code carefully. CustomHireDate must be child class of Validation Attribute
class. Than we have to override IsValid method of ValidationAttribute class. In this overridden
method we can provide our own logic for validation.

Here is code for Department Model Class used in Employee Model.

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;

namespace MVCDemo.Models
{
public class Department
{

[Display(Name = "Select Department")]


public int DepartmentID { get; set; }
public string Name { get; set; }

public List<SelectListItem> getDepartmentList()


{
return new List<SelectListItem>
{
new SelectListItem { Value = "1", Text = "Marketing"
},
new SelectListItem { Value = "2", Text = "Finance" },
new SelectListItem { Value = "3", Text = "Operations
Management" },
new SelectListItem { Value = "4", Text = "IT" },
new SelectListItem { Value = "5", Text = "Human
Resource" }

};
}
}
}

Here is code for EmployeeController class.

using MVCDemo.DAL;
using MVCDemo.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MVCDemo.Controllers
{
public class EmployeeController : Controller
{
// GET: Employee
public ActionResult Create()
{
ViewBag.DepartmentsList = getDepartmentList();

return View();
}
[HttpPost]
public ActionResult Create(Employee emp)
{
/*
1.ModelState is a property of controller class that helps
to validate form data in server side.
2. If any of the model fields are not matching with their
defined type(Employee Model Class in our class), then
ModelState.IsValid will return false.
*/
if (ModelState.IsValid) {
//Code to insert data
}
ViewBag.DepartmentsList = getDepartmentList();
return View();
}

private List<SelectListItem> getDepartmentList()


{
return new Department().getDepartmentList();
}
}
}

Add Create view in Employee Folder within views Folder.

Paste following code in the Create View.

@model MVCDemo.Models.Employee

@{
Layout = null;
}

<!DOCTYPE html>

<html>
<head>
<meta name="viewport" content="width=device-width" />
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
<title>Employee Information</title>
</head>
<body>
@using (Html.BeginForm("Create","Employee"))
{
<div class="h4">
@Html.ActionLink("Back to Main Page", "Index")
</div>

<div class="form-horizontal">
<h4 class="h1 text-center">Employee Information</h4>
<hr />

<div class="form-group">
@Html.LabelFor(model => model.FirstName, htmlAttributes:
new { @class = "control-label col-md-2" })
<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" })
<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">
@Html.LabelFor(model => model.Gender, htmlAttributes: new
{ @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Gender, new {
htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Gender, "",
new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.EmailAddress,
htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.EmailAddress, new {
htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model =>
model.EmailAddress, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.City, htmlAttributes: new {
@class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.City, new {
htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.City, "",
new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.Salary, htmlAttributes: new
{ @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Salary, new {
htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Salary, "",
new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.Age, htmlAttributes: new {
@class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Age, new {
htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Age, "", new
{ @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.EducationLevel,
htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.EducationLevel, new {
htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model =>
model.EducationLevel, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.HireData, htmlAttributes:
new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.HireData, new {
htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.HireData,
"", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.Department.DepartmentID,
htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(x => x.Department.DepartmentID,
(List<SelectListItem>)ViewBag.DepartmentsList)
</div>
</div>

<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-
default" />
</div>
</div>
</div>
}

</body>
</html>

In the Create view we have used bootstrap to beautify look and feel of UI. Html.LabelFor
helper automatically render the display name of model property on the view. This is just like
html label tag.

@Html.EditorFor generates input control just like @Html.TextBox but the key
difference is that Html.EditorFor helper method generates input control based on underlying
datatype specified in the model class. For example the data type of salary in Model
class so you can not specify alphabets here. Only number is allowed.

@Html.ValidationMessageFor displays a validation message if the user input does


not fulfill the validation criteria specified in the given property of the model class.
For example in the case of age input appropriate validation message will be displayed in case
of rules violation i.e. The age field is required in case of empty input and age must be
between 20 and 60 in case of invalid range.

@Html.ActionLink is used navigate from on view to other. In this case it will render the
index view of current controller (Employee Controller).

Note: The given Data Control (For HireDate) will only work in Google Chrome or Edge
Browsers. In advance lectures we will discuss use of JQuery Date Picker to resolve this
issue.

Fetching Data from Database using DataReader Object


There are two techniques to access and retrieve data from database in C# Ado.net. The one of
these two is the use of DataReader Object. DataReader is used to retrieve a forward-only as
well as read-only stream of data from a database (SQL Server in our case). Forward only
means you cannot access the data in previous row or you cannot read a random row of data.
The general syntax for retrieving data from SQL server is as following

SqlDataReader dataReader = sqlCommand.ExecuteReader();

Here we are using ExecuteReader Method to fetch data from database. Use of DataReader
class can enhance performance of application as it used connected approached and hold just
one row at a time.

Our program reads data rows one by one in a loop and store each column information in
relevant variable of model class object.

Now we will have an example code to clarify these all concepts. Create two tables Employee
and Department in database as described in the following screenshots.
Update Employee Entity class as following.

using MVCDemo.Models;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;

using System.Web;

namespace MVCDemo.DAL
{
public class EmployeeEntity
{
string ConnectionString = @"data source=DESKTOP-
E28E3Q2\SQLEXPRESS;initial catalog=EMS;integrated security=True";
SqlConnection sqlConnection = null;
SqlCommand cmd = null;
public int insert(Employee employee)
{
int effectedRows = 0;
try
{
sqlConnection = new SqlConnection(ConnectionString);
string query = @"insert into
Employee(FirstName,LastName,Gender,Age,EducationLevel,Salary,EmailAddr
ess,HireDate,City,DepartmentId)
values('" + employee.FirstName + "','"
+ employee.LastName + "','" + employee.Gender + "','" + employee.Age +
"','" + employee.EducationLevel + "','" + employee.Salary + "','" +
employee.EmailAddress + "','" + employee.HireData + "','"+ employee
.City+ "','" + employee.Department.DepartmentID + "')";
sqlConnection.Open();
cmd = new SqlCommand(query, sqlConnection);
effectedRows = cmd.ExecuteNonQuery();
sqlConnection.Close();
return effectedRows;
}
catch (Exception exp)
{
return effectedRows;

}
}

public List<Employee> GetList()


{
List<Employee> EmployeeList = new List<Employee>();
sqlConnection = new SqlConnection(ConnectionString);
string query = @"select * from Employee emp inner join
Department dept on emp.DepartmentID=dept.DepartmentID";

sqlConnection.Open();
cmd = new SqlCommand(query, sqlConnection);
SqlDataReader dataReader = cmd.ExecuteReader();

while (dataReader.Read())
{
EmployeeList.Add(new Employee
{

FirstName = dataReader["FirstName"].ToString(),
LastName = dataReader["LastName"].ToString(),
Gender = dataReader["Gender"].ToString(),
EmailAddress =
dataReader["EmailAddress"].ToString(),
City = dataReader["City"].ToString(),
Salary
=Convert.ToInt32(dataReader["Salary"].ToString()),
Age=
Convert.ToInt32(dataReader["Age"].ToString()),
EducationLevel =
Convert.ToInt32(dataReader["EducationLevel"].ToString()),
Department=new Department {
DepartmentID=
Convert.ToInt32(dataReader["DepartmentID"].ToString()),
Name = dataReader["Name"].ToString()
},
HireData=
DateTime.Parse(dataReader["HireDate"].ToString())

});
}

sqlConnection.Close();

return EmployeeList;
}
}
}

Create a new Class Department Entity in DAL Folder and paste following code.

using MVCDemo.Models;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
namespace MVCDemo.DAL
{
public class DepartmentEntity
{
string ConnectionString = @"data source=DESKTOP-
E28E3Q2\SQLEXPRESS;initial catalog=EMS;integrated security=True";
SqlConnection sqlConnection = null;
SqlCommand cmd = null;

//Fetching Deparment list from data base to populate dropdown


in view
public List<Department> GetList()
{
List<Department> DepartmentList = new List<Department>();
sqlConnection = new SqlConnection(ConnectionString);
string query = @"select * from Department";
sqlConnection.Open();
cmd = new SqlCommand(query, sqlConnection);
SqlDataReader dataReader = cmd.ExecuteReader();

while (dataReader.Read())
{

DepartmentList.Add(new Department
{
DepartmentID =
Convert.ToInt32(dataReader["DepartmentID"].ToString()),
Name = dataReader["Name"].ToString()
});
}

sqlConnection.Close();

return DepartmentList;
}
}
}

Update the Model class Department and write following code.

using MVCDemo.DAL;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;

namespace MVCDemo.Models
{
public class Department
{

[Display(Name = "Select Department")]


public int DepartmentID { get; set; }
public string Name { get; set; }

//populating select list item from data base for dropdown

public List<SelectListItem> getDepartmentList()


{
DepartmentEntity entity = new DepartmentEntity();
List<Department> DepartmentList = entity.GetList();
List<SelectListItem> ItemsList = new
List<SelectListItem>();
foreach (var item in DepartmentList)
{
ItemsList.Add(new SelectListItem { Value =
item.DepartmentID.ToString(), Text =item.Name });
}
return ItemsList;
}
}
}

Update the code of Employee controller as following.

using MVCDemo.DAL;
using MVCDemo.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MVCDemo.Controllers
{
public class EmployeeController : Controller
{
// GET: Employee

public ActionResult Index()


{
//Fetch all Employee records from data base
ViewBag.DepartmentsList = getDepartmentList();
EmployeeEntity entity = new EmployeeEntity();
List<Employee> Employeelist = entity.GetList();
return View(Employeelist);
}
public ActionResult Create()
{
ViewBag.DepartmentsList = getDepartmentList();
return View();
}
[HttpPost]
public ActionResult Create(Employee emp)
{
/*
1.ModelState is a property of controller class that helps
to validate form data in server side.
2. If any of the model fields are not matching with their
defined type(Employee Model Class in our class), then
ModelState.IsValid will return false.
*/
if (ModelState.IsValid) {
EmployeeEntity entity = new EmployeeEntity();
int effectedRows= entity.insert(emp);
if (effectedRows > 0)
{
ViewBag.SuccessMessage = "Data Inserted
Successfully!";
}
}
ViewBag.DepartmentsList = getDepartmentList();
return View();
}

private List<SelectListItem> getDepartmentList()


{
return new Department().getDepartmentList();
}
}}

Add Index view in Employee Folder to show all employees. The code for Index view is as
following.

@model IEnumerable<MVCDemo.Models.Employee>

@{
Layout = null;
}

<!DOCTYPE html>

<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Employee List</title>
</head>
<body>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table class="table" border="1">
<tr>
<th>
@Html.DisplayNameFor(model => model.FirstName)
</th>
<th>
@Html.DisplayNameFor(model => model.LastName)
</th>
<th>
@Html.DisplayNameFor(model => model.Gender)
</th>
<th>
@Html.DisplayNameFor(model => model.EmailAddress)
</th>
<th>
@Html.DisplayNameFor(model => model.City)
</th>
<th>
@Html.DisplayNameFor(model => model.Salary)
</th>
<th>
@Html.DisplayNameFor(model => model.Age)
</th>
<th>
@Html.DisplayNameFor(model => model.EducationLevel)
</th>
<th>
@Html.DisplayNameFor(model => model.HireData)
</th>
<th>
@Html.DisplayNameFor(model => model.Department.Name)
</th>
<th></th>
</tr>
@if (Model != null && Model.Count() > 0)
{
foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.FirstName)
</td>
<td>
@Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
@Html.DisplayFor(modelItem => item.Gender)
</td>
<td>
@Html.DisplayFor(modelItem => item.EmailAddress)
</td>
<td>
@Html.DisplayFor(modelItem => item.City)
</td>
<td>
@Html.DisplayFor(modelItem => item.Salary)
</td>
<td>
@Html.DisplayFor(modelItem => item.Age)
</td>
<td>
@Html.DisplayFor(modelItem => item.EducationLevel)
</td>
<td>
@Html.DisplayFor(modelItem => item.HireData)
</td>

<td>
@Html.DisplayFor(modelItem => item.Department.Name)
</td>

</tr>
}
}
else
{
<tr>

<td colspan="10">
No Record Found
</td>
</tr>
}
</table>
</body>
</html>

Assignment #5
Dear students read the given lectures carefully as per the course objectives mentioned on the top
and carryout the assignment as per following instructions

1. Submission Date: Sunday 12-April-2020 at 11:59 PM. This will also count as your
Attendance for this week.

2. You must prepare handwritten Assignment with implementation in the form of project.

3. Send it to respective course teacher (after scanning it) for assessment by email only.

Part 1: Create a Form to save Mobile Data in database. Apply specified validation within
parenthesis using concepts provided in this lecture. It must have following fields:
1: IMEI Number 2: Operating System (android as well as iOS and populate dropdown from database
table named OS) 3: Released Date (Must not greater than today)
4: Color (length must be great than 2 and less than 15) 5: Weight in grams
6: Model Number 7: Ram (Must be greater than 1 GB and less than 8 GB)
8: Price (Must be greater than 10,000 and less than 20, 0000)
Part 2: Create another view to display all saved information (in SQL server DB) in Mobile Data
using Table Tag.

You might also like