Part 24 - Deleting database records using post request in mvc
Suggested Videos
Part 21 - Including and excluding properties from model binding using bind attribute
Part 22 - Including and excluding properties from model binding using interfaces
Part 23 - Why deleting database records using get request is bad
In this video we will discuss
1. Deleting database records using POST request
2. Showing the client side javascript confirmation dialog box before deleting
Please watch Part 23, before proceeding.
Step 1: Mark "Delete" action method in "Employee" controller with [HttpPost] attribute. With this change, the "Delete" method will no longer respond to "GET" request. At this point, if we run the application and click on "Delete" link on the "Index" view, we get an error stating - "The resource cannot be found"
[HttpPost]
public ActionResult Delete(int id)
{
EmployeeBusinessLayer employeeBusinessLayer =
new EmployeeBusinessLayer();
employeeBusinessLayer.DeleteEmployee(id);
return RedirectToAction("Index");
}
Step 2: In "Index.cshtml"
REPLACE THE FOLLOWING CODE
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Gender)
</td>
<td>
@Html.DisplayFor(modelItem => item.City)
</td>
<td>
@Html.DisplayFor(modelItem => item.DateOfBirth)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
@Html.ActionLink("Details", "Details", new { id=item.ID }) |
@Html.ActionLink("Delete", "Delete", new { id=item.ID })
</td>
</tr>
}
WITH
@foreach (var item in Model)
{
using (Html.BeginForm("Delete", "Employee", new { id = item.ID }))
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Gender)
</td>
<td>
@Html.DisplayFor(modelItem => item.City)
</td>
<td>
@Html.DisplayFor(modelItem => item.DateOfBirth)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id = item.ID }) |
<input type="submit" value="Delete" />
</td>
</tr>
}
}
Notice that, we are using "Html.BeginForm()" html helper to generate a form tag.
Step 3: To include client-side confirmation, before the data can be deleted, add the "onclick" attribute to "Delete" button as shown below.
<input type="submit" value="Delete" onclick="return confirm('Are you sure you want to delete record with ID = @item.ID');" />
Part 21 - Including and excluding properties from model binding using bind attribute
Part 22 - Including and excluding properties from model binding using interfaces
Part 23 - Why deleting database records using get request is bad
In this video we will discuss
1. Deleting database records using POST request
2. Showing the client side javascript confirmation dialog box before deleting
Please watch Part 23, before proceeding.
Step 1: Mark "Delete" action method in "Employee" controller with [HttpPost] attribute. With this change, the "Delete" method will no longer respond to "GET" request. At this point, if we run the application and click on "Delete" link on the "Index" view, we get an error stating - "The resource cannot be found"
[HttpPost]
public ActionResult Delete(int id)
{
EmployeeBusinessLayer employeeBusinessLayer =
new EmployeeBusinessLayer();
employeeBusinessLayer.DeleteEmployee(id);
return RedirectToAction("Index");
}
Step 2: In "Index.cshtml"
REPLACE THE FOLLOWING CODE
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Gender)
</td>
<td>
@Html.DisplayFor(modelItem => item.City)
</td>
<td>
@Html.DisplayFor(modelItem => item.DateOfBirth)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
@Html.ActionLink("Details", "Details", new { id=item.ID }) |
@Html.ActionLink("Delete", "Delete", new { id=item.ID })
</td>
</tr>
}
WITH
@foreach (var item in Model)
{
using (Html.BeginForm("Delete", "Employee", new { id = item.ID }))
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Gender)
</td>
<td>
@Html.DisplayFor(modelItem => item.City)
</td>
<td>
@Html.DisplayFor(modelItem => item.DateOfBirth)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id = item.ID }) |
<input type="submit" value="Delete" />
</td>
</tr>
}
}
Notice that, we are using "Html.BeginForm()" html helper to generate a form tag.
Step 3: To include client-side confirmation, before the data can be deleted, add the "onclick" attribute to "Delete" button as shown below.
<input type="submit" value="Delete" onclick="return confirm('Are you sure you want to delete record with ID = @item.ID');" />
Part 25 - Insert update delete in mvc using entity framework
Suggested Videos
Part 22 - Including and excluding properties from model binding using interfaces
Part 23 - Why deleting database records using get request is bad
Part 24 - Deleting database records using post request in mvc
In this video we will discuss, selecting, inserting, updating and deleting data in mvc using entity framework. Please watch Part 24, before proceeding.
We will be using tables tblDepartment and tblEmployee for this demo. You can get the sql script to create and populate these tables from Part 10 of this video series.
Step 1: Create a new asp.net mvc 4 web application.
Step 2: Right click on the "Models" folder and add "ADO.NET Entity Data Model". Set Name = EmployeeDataModel.edmx.

On the subsequent screen, select "Generate from database" option and click "Next".
On "Choose your data connection screen", click on "New Connection" button.
Specify the sql server name. In my case, I have sql server installed on my local machine. So I have set "Server Name=(local)". From "Select or enter a database name" dropdownlist, select the Database name and click "OK".

Click "Next".
On "Choose your database objects" screen, expand "Tables" and select "tblDepartment" and "tblEmployee" tables. Set "Model Namespace=Models" and click "Finish"

At this point we should have tblDepartment and tblEmployee entities generated.
a) Change tblDepartment to Department
b) Change tblEmployee to Employee
c) Change tblEmployees nvigation property to Employees
d) Change tblDepartment nvigation property to Department

Build the solution.
Step 3: Right click on the "Controllers" folder and select Add - Controller. Set
Name = EmployeeController
Template = MVC controller with read/write actions and views, using Entity Framework
Model class = Employee(MVCDemo.Models)
Data Context Class = EmployeeContext(MVCDemo.Models)
Views = Razor
Finally click "Add".
At this point you should have the following files automatically added.
1. EmployeeController.cs file in "Controllers" folder
2. Index, Create, Edit, Detail and Delete views in "Employee" folder.
On Create and Edit views, please delete the following scripts section. We will discuss these in a later video session.
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
At this point, if you run the application by pressing CTRL + F5, you will get an error stating - The resource cannot be found. This is because, by default, the application goes to "HOME" controller and "Index" action.
To fix this,
1. Open "RouteConfig.cs" file from "App_Start" folder
2. Set Controller = "Employee"
Run the application again. Notice that, all the employees are listed on the index view. We can also create a new employee, edit an employee, view their full details and delete an employee as well. However, there are few issues, with each of the views, which we will address in our upcoming videos.
Part 22 - Including and excluding properties from model binding using interfaces
Part 23 - Why deleting database records using get request is bad
Part 24 - Deleting database records using post request in mvc
In this video we will discuss, selecting, inserting, updating and deleting data in mvc using entity framework. Please watch Part 24, before proceeding.
We will be using tables tblDepartment and tblEmployee for this demo. You can get the sql script to create and populate these tables from Part 10 of this video series.
Step 1: Create a new asp.net mvc 4 web application.
Step 2: Right click on the "Models" folder and add "ADO.NET Entity Data Model". Set Name = EmployeeDataModel.edmx.

On the subsequent screen, select "Generate from database" option and click "Next".
On "Choose your data connection screen", click on "New Connection" button.
Specify the sql server name. In my case, I have sql server installed on my local machine. So I have set "Server Name=(local)". From "Select or enter a database name" dropdownlist, select the Database name and click "OK".

Click "Next".
On "Choose your database objects" screen, expand "Tables" and select "tblDepartment" and "tblEmployee" tables. Set "Model Namespace=Models" and click "Finish"

At this point we should have tblDepartment and tblEmployee entities generated.
a) Change tblDepartment to Department
b) Change tblEmployee to Employee
c) Change tblEmployees nvigation property to Employees
d) Change tblDepartment nvigation property to Department

Build the solution.
Step 3: Right click on the "Controllers" folder and select Add - Controller. Set
Name = EmployeeController
Template = MVC controller with read/write actions and views, using Entity Framework
Model class = Employee(MVCDemo.Models)
Data Context Class = EmployeeContext(MVCDemo.Models)
Views = Razor
Finally click "Add".
At this point you should have the following files automatically added.
1. EmployeeController.cs file in "Controllers" folder
2. Index, Create, Edit, Detail and Delete views in "Employee" folder.
On Create and Edit views, please delete the following scripts section. We will discuss these in a later video session.
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
At this point, if you run the application by pressing CTRL + F5, you will get an error stating - The resource cannot be found. This is because, by default, the application goes to "HOME" controller and "Index" action.
To fix this,
1. Open "RouteConfig.cs" file from "App_Start" folder
2. Set Controller = "Employee"
Run the application again. Notice that, all the employees are listed on the index view. We can also create a new employee, edit an employee, view their full details and delete an employee as well. However, there are few issues, with each of the views, which we will address in our upcoming videos.
Part 26 - Customizing the autogenerated index view
Suggested Videos
Part 23 - Why deleting database records using get request is bad
Part 24 - Deleting database records using post request in mvc
Part 25 - Insert update delete in mvc using entity framework
In this video we will discuss, customizing the auto-generated index view. Please watch Part 25, before proceeding.
At the moment, the "Index" view is using "Name" as the column header for both employee name and department name. This is because "Name" column is used in both the database tables(tblEmployee & tblDepartment) and entity framework has used these column names to generate "Name" property in Employee and Department classes that are auto-generated.
I want to change the depratment column header to "Department Name" instead of just "Name". To achieve this, add a class file with "name=Department.cs" to "Models" folder.
Copy and paste the following code in "Department.cs" file
[MetadataType(typeof(DepartmentMetaData))]
public partial class Department
{
}
public class DepartmentMetaData
{
[Display(Name="Department Name")]
public string Name { get; set; }
}
With these changes run the application and notice the column name is displayed as Department Name. This is achieved by using "Display" attribute that is present in "System.ComponentModel.DataAnnotations" namespace.
If you are wondering why can't we apply "Display" attribute directly to the auto-generated "Department" class instead of creating another partial "Department" and DepartmentMetaData class. We can do it. There is nothing stopping us from doing it, but every time the Department class is auto-generated, our custom changes will be lost. This is the reason for creating another partial class, and applying our changes.
Part 23 - Why deleting database records using get request is bad
Part 24 - Deleting database records using post request in mvc
Part 25 - Insert update delete in mvc using entity framework
In this video we will discuss, customizing the auto-generated index view. Please watch Part 25, before proceeding.
At the moment, the "Index" view is using "Name" as the column header for both employee name and department name. This is because "Name" column is used in both the database tables(tblEmployee & tblDepartment) and entity framework has used these column names to generate "Name" property in Employee and Department classes that are auto-generated.
I want to change the depratment column header to "Department Name" instead of just "Name". To achieve this, add a class file with "name=Department.cs" to "Models" folder.
Copy and paste the following code in "Department.cs" file
[MetadataType(typeof(DepartmentMetaData))]
public partial class Department
{
}
public class DepartmentMetaData
{
[Display(Name="Department Name")]
public string Name { get; set; }
}
With these changes run the application and notice the column name is displayed as Department Name. This is achieved by using "Display" attribute that is present in "System.ComponentModel.DataAnnotations" namespace.
If you are wondering why can't we apply "Display" attribute directly to the auto-generated "Department" class instead of creating another partial "Department" and DepartmentMetaData class. We can do it. There is nothing stopping us from doing it, but every time the Department class is auto-generated, our custom changes will be lost. This is the reason for creating another partial class, and applying our changes.
Suggested Videos
Part 24 - Deleting database records using post request in mvc
Part 25 - Insert update delete in mvc using entity framework
Part 26 - Customizing the autogenerated index view
In this video we will discuss, customizing the auto-generated create view. Please watch Part 26, before proceeding.
At the moment, none of the fields on "Create" view are required. This means,when you click on the "Create" button without filling any data, NULL values are stored in all the columns of tblEmployee table.
So, how to make these fields on the "Create" view required?
Add [Required] attribute to the "Employee" class. The "Employee" class that is present in "EmployeeDataModel.Designer.cs" is auto-generated by the entity framework. There is no point in adding the [Required] attribute to this class, as we will loose the changes if the class is auto-generated again.
To achieve this, add a class file with "name=Employee.cs" to "Models" folder.
Copy and paste the following code in "Employee.cs" file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace MVCDemo.Models
{
[MetadataType(typeof(EmployeeMetaData))]
public partial class Employee
{
}
public class EmployeeMetaData
{
[Required]
public string Name { get; set; }
[Required]
public string Gender { get; set; }
[Required]
public string City { get; set; }
[Required]
[Display(Name="Department")]
public int DepartmentId { get; set; }
}
}
At this point, run the application and click on the "Create" button without filling any data. Notice that we get validation error messages as expected. In a later video session, we will discuss changing the colour of the validation messages.
If you want "Select Department" as the first item in the "Department" dropdownlist on "Create" view, then,
REPLACE THE FOLLOWING LINE
@Html.DropDownList("DepartmentId", String.Empty)
WITH
@Html.DropDownList("DepartmentId", "Select Department")
Notice that, a textbox is used for gender. It is ideal to have a dropdownlist for gender rather than a textbox. To achieve this, make the following changes to "Create.cshtml" view.
REPLACE THE FOLLOWING CODE
@Html.EditorFor(model => model.Gender)
WITH
@Html.DropDownList("Gender", new List<SelectListItem>
{
new SelectListItem { Text = "Male", Value="Male" },
new SelectListItem { Text = "Female", Value="Female" }
}, "Select Gender")
Part 24 - Deleting database records using post request in mvc
Part 25 - Insert update delete in mvc using entity framework
Part 26 - Customizing the autogenerated index view
In this video we will discuss, customizing the auto-generated create view. Please watch Part 26, before proceeding.
At the moment, none of the fields on "Create" view are required. This means,when you click on the "Create" button without filling any data, NULL values are stored in all the columns of tblEmployee table.
So, how to make these fields on the "Create" view required?
Add [Required] attribute to the "Employee" class. The "Employee" class that is present in "EmployeeDataModel.Designer.cs" is auto-generated by the entity framework. There is no point in adding the [Required] attribute to this class, as we will loose the changes if the class is auto-generated again.
To achieve this, add a class file with "name=Employee.cs" to "Models" folder.
Copy and paste the following code in "Employee.cs" file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace MVCDemo.Models
{
[MetadataType(typeof(EmployeeMetaData))]
public partial class Employee
{
}
public class EmployeeMetaData
{
[Required]
public string Name { get; set; }
[Required]
public string Gender { get; set; }
[Required]
public string City { get; set; }
[Required]
[Display(Name="Department")]
public int DepartmentId { get; set; }
}
}
At this point, run the application and click on the "Create" button without filling any data. Notice that we get validation error messages as expected. In a later video session, we will discuss changing the colour of the validation messages.
If you want "Select Department" as the first item in the "Department" dropdownlist on "Create" view, then,
REPLACE THE FOLLOWING LINE
@Html.DropDownList("DepartmentId", String.Empty)
WITH
@Html.DropDownList("DepartmentId", "Select Department")
Notice that, a textbox is used for gender. It is ideal to have a dropdownlist for gender rather than a textbox. To achieve this, make the following changes to "Create.cshtml" view.
REPLACE THE FOLLOWING CODE
@Html.EditorFor(model => model.Gender)
WITH
@Html.DropDownList("Gender", new List<SelectListItem>
{
new SelectListItem { Text = "Male", Value="Male" },
new SelectListItem { Text = "Female", Value="Female" }
}, "Select Gender")
Part 28 - Customizing the autogenerated edit view
Suggested Videos
Part 25 - Insert update delete in mvc using entity framework
Part 26 - Customizing the autogenerated index view
Part 27 - Customizing the autogenerated create view
In this video we will discuss, customizing the auto-generated edit view. Please watch Part 27, before proceeding.
If you want "Select Department" as the first item in the "Department" dropdownlist on "Edit" view, then,
REPLACE THE FOLLOWING LINE
@Html.DropDownList("DepartmentId", String.Empty)
WITH
@Html.DropDownList("DepartmentId", "Select Department")
Notice that, a textbox is used for gender. It is ideal to have a dropdownlist for gender rather than a textbox. To achieve this, make the following changes to "Edit.cshtml" view.
REPLACE THE FOLLOWING CODE
@Html.EditorFor(model => model.Gender)
WITH
@Html.DropDownList("Gender", new List<SelectListItem>
{
new SelectListItem { Text = "Male", Value="Male" },
new SelectListItem { Text = "Female", Value="Female" }
}, "Select Gender")
Let's make "Name" non-editable. To achieve this
CHANGE THE FOLLOWING CODE IN EDIT.CSHTML
@Html.EditorFor(model => model.Name)
TO
@Html.DisplayFor(model => model.Name)
@Html.HiddenFor(model => model.Name)
At this point, we will still be able to change "Name" property of the employee, using tools like fiddler. We discussed this in Part 19 of this video series. There are several ways to prevent "Name" property from being updated.
1. Use UpdateModel() function and pass include and exclude list as a parameter - Discussed in Part 20
2. Use Bind attribute - Discussed in Part 21
3. Use interfaces - Discussed in Part 22
Now, let's discuss using BIND attribute to prevent updating "Name" property using tools like fiddler. Along the way, I will demonstrate adding model validation errors dynamically.
Change the implementation of "Edit" controller action method, that responds to [HttpPost] request as shown below
[HttpPost]
public ActionResult Edit([Bind(Exclude="Name")] Employee employee)
{
Employee employeeFromDB = db.Employees.Single(x => x.EmployeeId == employee.EmployeeId);
employeeFromDB.EmployeeId = employee.EmployeeId;
employeeFromDB.Gender = employee.Gender;
employeeFromDB.City = employee.City;
employeeFromDB.DepartmentId = employee.DepartmentId;
employee.Name = employeeFromDB.Name;
if (ModelState.IsValid)
{
db.ObjectStateManager.ChangeObjectState(employeeFromDB, EntityState.Modified);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.DepartmentId = new SelectList(db.Departments, "Id", "Name", employee.DepartmentId);
return View(employee);
}
Please note that, we have excluded "Name" property from model binding using "Bind" attribute. Even without BIND attribute, users will not be able to change the "NAME" of the employee, as we are copying only the required properties(Excluding NAME property) from "employee" object to "employeeFromDB" which in turn is persisted to the database. Since, I want to demonstrate adding model validation errors dynamically, let the attribute be there.
At this point if we run the application and click on "Save" button on "Edit" view, we get a validation error stating - The Name field is required. This is because "Name" property is decorated with [Required] attribute in "Employee.cs" file. To prevent the validation error, remove the [Required] attribute.
The problem with this change is that, "Name" field on "Create" view is no longer mandatory. This means we will now be able to create a new employee, without NAME. To fix the "Create" view, let's add model validation errors dynamically. Change the implementation of "Create" controller action method that responds to [HttpPost] request as shown below.
[HttpPost]
public ActionResult Create(Employee employee)
{
if (string.IsNullOrEmpty(employee.Name))
{
ModelState.AddModelError("Name", "The Name field is required.");
}
if (ModelState.IsValid)
{
db.Employees.AddObject(employee);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.DepartmentId = new SelectList(db.Departments, "Id", "Name", employee.DepartmentId);
return View(employee);
}
Part 25 - Insert update delete in mvc using entity framework
Part 26 - Customizing the autogenerated index view
Part 27 - Customizing the autogenerated create view
In this video we will discuss, customizing the auto-generated edit view. Please watch Part 27, before proceeding.
If you want "Select Department" as the first item in the "Department" dropdownlist on "Edit" view, then,
REPLACE THE FOLLOWING LINE
@Html.DropDownList("DepartmentId", String.Empty)
WITH
@Html.DropDownList("DepartmentId", "Select Department")
Notice that, a textbox is used for gender. It is ideal to have a dropdownlist for gender rather than a textbox. To achieve this, make the following changes to "Edit.cshtml" view.
REPLACE THE FOLLOWING CODE
@Html.EditorFor(model => model.Gender)
WITH
@Html.DropDownList("Gender", new List<SelectListItem>
{
new SelectListItem { Text = "Male", Value="Male" },
new SelectListItem { Text = "Female", Value="Female" }
}, "Select Gender")
Let's make "Name" non-editable. To achieve this
CHANGE THE FOLLOWING CODE IN EDIT.CSHTML
@Html.EditorFor(model => model.Name)
TO
@Html.DisplayFor(model => model.Name)
@Html.HiddenFor(model => model.Name)
At this point, we will still be able to change "Name" property of the employee, using tools like fiddler. We discussed this in Part 19 of this video series. There are several ways to prevent "Name" property from being updated.
1. Use UpdateModel() function and pass include and exclude list as a parameter - Discussed in Part 20
2. Use Bind attribute - Discussed in Part 21
3. Use interfaces - Discussed in Part 22
Now, let's discuss using BIND attribute to prevent updating "Name" property using tools like fiddler. Along the way, I will demonstrate adding model validation errors dynamically.
Change the implementation of "Edit" controller action method, that responds to [HttpPost] request as shown below
[HttpPost]
public ActionResult Edit([Bind(Exclude="Name")] Employee employee)
{
Employee employeeFromDB = db.Employees.Single(x => x.EmployeeId == employee.EmployeeId);
employeeFromDB.EmployeeId = employee.EmployeeId;
employeeFromDB.Gender = employee.Gender;
employeeFromDB.City = employee.City;
employeeFromDB.DepartmentId = employee.DepartmentId;
employee.Name = employeeFromDB.Name;
if (ModelState.IsValid)
{
db.ObjectStateManager.ChangeObjectState(employeeFromDB, EntityState.Modified);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.DepartmentId = new SelectList(db.Departments, "Id", "Name", employee.DepartmentId);
return View(employee);
}
Please note that, we have excluded "Name" property from model binding using "Bind" attribute. Even without BIND attribute, users will not be able to change the "NAME" of the employee, as we are copying only the required properties(Excluding NAME property) from "employee" object to "employeeFromDB" which in turn is persisted to the database. Since, I want to demonstrate adding model validation errors dynamically, let the attribute be there.
At this point if we run the application and click on "Save" button on "Edit" view, we get a validation error stating - The Name field is required. This is because "Name" property is decorated with [Required] attribute in "Employee.cs" file. To prevent the validation error, remove the [Required] attribute.
The problem with this change is that, "Name" field on "Create" view is no longer mandatory. This means we will now be able to create a new employee, without NAME. To fix the "Create" view, let's add model validation errors dynamically. Change the implementation of "Create" controller action method that responds to [HttpPost] request as shown below.
[HttpPost]
public ActionResult Create(Employee employee)
{
if (string.IsNullOrEmpty(employee.Name))
{
ModelState.AddModelError("Name", "The Name field is required.");
}
if (ModelState.IsValid)
{
db.Employees.AddObject(employee);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.DepartmentId = new SelectList(db.Departments, "Id", "Name", employee.DepartmentId);
return View(employee);
}
Part 29 - Using data transfer object as the model in mvc
Suggested Videos
Part 26 - Customizing the auto-generated index view
Part 27 - Customizing the auto-generated create view
Part 28 - Customizing the auto-generated edit view
In this video we will discuss, using data transfer object as the model in mvc. Please watch Part 28, before proceeding.
Let's say the business requirement is such that, we want to display total number of employees by department as shown below. At the moment, either the Employee or Department class does not have Total property. This is one example, where a Data Transfer Object can be used as a model.

Right click on the "Models" folder and add a class with name="DepartmentTotals.cs". Copy and paste the following code.
public class DepartmentTotals
{
public string Name { get; set; }
public int Total { get; set; }
}
Now add the following "EmployeesByDepartment" controller action method to EmployeeController class.
public ActionResult EmployeesByDepartment()
{
var departmentTotals = db.Employees.Include("Department")
.GroupBy(x => x.Department.Name)
.Select(y => new DepartmentTotals
{
Name = y.Key, Total = y.Count()
}).ToList();
return View(departmentTotals);
}
At this point, build the solution, so that the newly added DepartmentTotals class is compiled.
Now right click on "EmployeesByDepartment" action method in "EmployeeController" and select "Add View" from the context menu.
View name = EmployeesByDepartment
View engine = Razor
Select "Create a strongly-typed view" checkbox
Model class = DepartmentTotals
Model class = DepartmentTotals
To list the employees in ascending order of total employee, use OrderBy() LINQ method as shown below.
var departmentTotals = db.Employees.Include("Department")
.GroupBy(x => x.Department.Name)
.Select(y => new DepartmentTotals
{
Name = y.Key, Total = y.Count()
}).ToList().OrderBy(y => y.Total);
To sort the list in descending order use, OrderByDescending() LINQ method.
var departmentTotals = db.Employees.Include("Department")
.GroupBy(x => x.Department.Name)
.Select(y => new DepartmentTotals
{
Name = y.Key, Total = y.Count()
}).ToList().OrderByDescending(y => y.Total);
return View(departmentTotals);
Part 26 - Customizing the auto-generated index view
Part 27 - Customizing the auto-generated create view
Part 28 - Customizing the auto-generated edit view
In this video we will discuss, using data transfer object as the model in mvc. Please watch Part 28, before proceeding.
Let's say the business requirement is such that, we want to display total number of employees by department as shown below. At the moment, either the Employee or Department class does not have Total property. This is one example, where a Data Transfer Object can be used as a model.

Right click on the "Models" folder and add a class with name="DepartmentTotals.cs". Copy and paste the following code.
public class DepartmentTotals
{
public string Name { get; set; }
public int Total { get; set; }
}
Now add the following "EmployeesByDepartment" controller action method to EmployeeController class.
public ActionResult EmployeesByDepartment()
{
var departmentTotals = db.Employees.Include("Department")
.GroupBy(x => x.Department.Name)
.Select(y => new DepartmentTotals
{
Name = y.Key, Total = y.Count()
}).ToList();
return View(departmentTotals);
}
At this point, build the solution, so that the newly added DepartmentTotals class is compiled.
Now right click on "EmployeesByDepartment" action method in "EmployeeController" and select "Add View" from the context menu.
View name = EmployeesByDepartment
View engine = Razor
Select "Create a strongly-typed view" checkbox
Model class = DepartmentTotals
Model class = DepartmentTotals
To list the employees in ascending order of total employee, use OrderBy() LINQ method as shown below.
var departmentTotals = db.Employees.Include("Department")
.GroupBy(x => x.Department.Name)
.Select(y => new DepartmentTotals
{
Name = y.Key, Total = y.Count()
}).ToList().OrderBy(y => y.Total);
To sort the list in descending order use, OrderByDescending() LINQ method.
var departmentTotals = db.Employees.Include("Department")
.GroupBy(x => x.Department.Name)
.Select(y => new DepartmentTotals
{
Name = y.Key, Total = y.Count()
}).ToList().OrderByDescending(y => y.Total);
return View(departmentTotals);
Part 30 - View engines in asp.net mvc
Suggested Videos
Part 27 - Customizing the auto-generated create view
Part 28 - Customizing the auto-generated edit view
Part 29 - Using data transfer object as the model in mvc
In this video we will discuss, different view engines that are available in asp.net mvc. Please watch Part 29, before proceeding.
Out of the box asp.net offers the following 2 view engines.
1. ASPX
2. Razor
There are 3 possible interview questions here, to test your understanding of view engines.
1. What is the difference between RAZOR and ASPX view engines?
It mostly, boils down to the syntax. Otherwise there are no major differences between the two. In ASPX view engine, the server side script is wrapped between <% %>, where as in RAZOR we use @. Personally, I prefer using RAZOR views, as it is very easy to switch between HTML and Code.
Depending on the programming language you have chosen, RAZOR views have the extension of .CSHTML or .VBHTML, where as ASPX views has the extension of .ASPX
2. Is it possible, to have both RAZOR and ASPX views in one application?
Yes, when you right click on any controller action method, and select "Add View" from the context menu, you will have the option to choose the view engine of your choice from the "Add View" dialog box.
3. Is it possible, to use a third party view engine with asp.net mvc?
ASP.NET MVC is designed with extensibility in mind. So, it's very easy to include third party view engine as well. We will discuss this in detail in our next video.
Part 27 - Customizing the auto-generated create view
Part 28 - Customizing the auto-generated edit view
Part 29 - Using data transfer object as the model in mvc
In this video we will discuss, different view engines that are available in asp.net mvc. Please watch Part 29, before proceeding.
Out of the box asp.net offers the following 2 view engines.
1. ASPX
2. Razor
There are 3 possible interview questions here, to test your understanding of view engines.
1. What is the difference between RAZOR and ASPX view engines?
It mostly, boils down to the syntax. Otherwise there are no major differences between the two. In ASPX view engine, the server side script is wrapped between <% %>, where as in RAZOR we use @. Personally, I prefer using RAZOR views, as it is very easy to switch between HTML and Code.
Depending on the programming language you have chosen, RAZOR views have the extension of .CSHTML or .VBHTML, where as ASPX views has the extension of .ASPX
2. Is it possible, to have both RAZOR and ASPX views in one application?
Yes, when you right click on any controller action method, and select "Add View" from the context menu, you will have the option to choose the view engine of your choice from the "Add View" dialog box.
3. Is it possible, to use a third party view engine with asp.net mvc?
ASP.NET MVC is designed with extensibility in mind. So, it's very easy to include third party view engine as well. We will discuss this in detail in our next video.
Suggested Videos
Part 28 - Customizing the auto-generated edit view
Part 29 - Using data transfer object as the model
Part 30 - View engines
Out of the box ASP.NET MVC supports the following 2 view engines
1. ASPX
2. Razor
In addition to the above 2 view engines, there are several custom view engines that can be used with asp.net mvc. The following are a few of these custom view engines.
1. Spark
2. NHaml
3. SharpDOM
4. Brail etc....
For example, if you want to use Spark as the view engine for your asp.net mvc 4 project, then install Spark.Web.Mvc4 using NuGet Package Manager.
At this point, right click on any controller action method and select "Add View" from the context menu. Notice that, "View Engine" dropdownlist in "Add View" dialog box only shows - Razor and ASPX view engines. If you want the "Spark" view engine to be listed, then, we need to register "Spark View Engine" templates.
Step 1: Navigate to the following path and create a folder with name="Spark". Spark specific templates must be copied into "Spark" folder.
C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ItemTemplates\CSharp\Web\MVC 4\CodeTemplates\AddView
Step 2: Create an xml file with in "Spark" folder. The name of the XML file must be "ViewEngine.xml" and must contain the following xml content.
<?xml version="1.0" encoding="utf-8" ?>
<ViewEngine DisplayName="Spark"
ViewFileExtension=".spark"
DefaultLayoutPage="~/Views/Shared/_Layout.spark"
PartialViewFileExtension=".spark" />
Now, right click on any controller action method and select "Add View" from the context menu. Notice that, "Spark" view engine is also listed.
Part 28 - Customizing the auto-generated edit view
Part 29 - Using data transfer object as the model
Part 30 - View engines
Out of the box ASP.NET MVC supports the following 2 view engines
1. ASPX
2. Razor
In addition to the above 2 view engines, there are several custom view engines that can be used with asp.net mvc. The following are a few of these custom view engines.
1. Spark
2. NHaml
3. SharpDOM
4. Brail etc....
For example, if you want to use Spark as the view engine for your asp.net mvc 4 project, then install Spark.Web.Mvc4 using NuGet Package Manager.
At this point, right click on any controller action method and select "Add View" from the context menu. Notice that, "View Engine" dropdownlist in "Add View" dialog box only shows - Razor and ASPX view engines. If you want the "Spark" view engine to be listed, then, we need to register "Spark View Engine" templates.
Step 1: Navigate to the following path and create a folder with name="Spark". Spark specific templates must be copied into "Spark" folder.
C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ItemTemplates\CSharp\Web\MVC 4\CodeTemplates\AddView
Step 2: Create an xml file with in "Spark" folder. The name of the XML file must be "ViewEngine.xml" and must contain the following xml content.
<?xml version="1.0" encoding="utf-8" ?>
<ViewEngine DisplayName="Spark"
ViewFileExtension=".spark"
DefaultLayoutPage="~/Views/Shared/_Layout.spark"
PartialViewFileExtension=".spark" />
Now, right click on any controller action method and select "Add View" from the context menu. Notice that, "Spark" view engine is also listed.
Part 32 - How does a controller find a view in mvc
Suggested Videos
Part 29 - Using data transfer object as the model
Part 30 - View engines
Part 31 - Using custom view engines
In this video, we will discuss the convention used by mvc to find views. Let's understand this with an example.
Notice that, the Index() action method does not specify the name of the view. So,
1. How does asp.net mvc know, which view to use
2. What locations does asp.net mvc search
public class EmployeeController : Controller
{
private EmployeeContext db = new EmployeeContext();
public ActionResult Index()
{
var employees = db.Employees.Include("Department");
return View(employees.ToList());
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
}
To find the answer for the above 2 questions, delete the "Index.cshtml" view from "Views/Employee" folder. Run the application, and notice that we get an error message stating
The view 'Index' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/Employee/Index.aspx
~/Views/Employee/Index.ascx
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
~/Views/Employee/Index.cshtml
~/Views/Employee/Index.vbhtml
~/Views/Shared/Index.cshtml
~/Views/Shared/Index.vbhtml
So, from the error message, it should be clear that, MVC looks for a view with the same name as that of the controller action method in the following locations
1. Views/Shared
2. Views/FolderNameMatchingControllerName
Please note that, the view extension can be any of the following
a).cshtml
b).vbhtml
c).aspx
d).ascx
If I have all of the following files in "Views/Employee" folder, then MVC picks up "Index.aspx"
a) Index.aspx
b) Index.cshtml
c) Index.vbhtml
d) Index.ascx
If you want to use "Index.cshtml" instead, then specify the full path as shown below.
public ActionResult Index()
{
var employees = db.Employees.Include("Department");
return View("~/Views/Employee/Index.cshtml", employees.ToList());
}
If you specify only the name of the view along with it's extension as shown below, you will get an error.
return View("Index.cshtml", employees.ToList());
If you want to use a view name which is not inside the views folder of the current controller, then specify the full path as shown below.
public ActionResult Index()
{
var employees = db.Employees.Include("Department");
return View("~/Views/Home/Index.aspx", employees.ToList());
}
Please note that asp.net mvc
1. Is all about convention over configuration
2. Views folder contains one folder for each controller and a "Shared" folder
3. Shared folder is used to store views shared between controllers. Master and Layout pages are stored in "Shared" folder.
Part 29 - Using data transfer object as the model
Part 30 - View engines
Part 31 - Using custom view engines
In this video, we will discuss the convention used by mvc to find views. Let's understand this with an example.
Notice that, the Index() action method does not specify the name of the view. So,
1. How does asp.net mvc know, which view to use
2. What locations does asp.net mvc search
public class EmployeeController : Controller
{
private EmployeeContext db = new EmployeeContext();
public ActionResult Index()
{
var employees = db.Employees.Include("Department");
return View(employees.ToList());
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
}
To find the answer for the above 2 questions, delete the "Index.cshtml" view from "Views/Employee" folder. Run the application, and notice that we get an error message stating
The view 'Index' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/Employee/Index.aspx
~/Views/Employee/Index.ascx
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
~/Views/Employee/Index.cshtml
~/Views/Employee/Index.vbhtml
~/Views/Shared/Index.cshtml
~/Views/Shared/Index.vbhtml
So, from the error message, it should be clear that, MVC looks for a view with the same name as that of the controller action method in the following locations
1. Views/Shared
2. Views/FolderNameMatchingControllerName
Please note that, the view extension can be any of the following
a).cshtml
b).vbhtml
c).aspx
d).ascx
If I have all of the following files in "Views/Employee" folder, then MVC picks up "Index.aspx"
a) Index.aspx
b) Index.cshtml
c) Index.vbhtml
d) Index.ascx
If you want to use "Index.cshtml" instead, then specify the full path as shown below.
public ActionResult Index()
{
var employees = db.Employees.Include("Department");
return View("~/Views/Employee/Index.cshtml", employees.ToList());
}
If you specify only the name of the view along with it's extension as shown below, you will get an error.
return View("Index.cshtml", employees.ToList());
If you want to use a view name which is not inside the views folder of the current controller, then specify the full path as shown below.
public ActionResult Index()
{
var employees = db.Employees.Include("Department");
return View("~/Views/Home/Index.aspx", employees.ToList());
}
Please note that asp.net mvc
1. Is all about convention over configuration
2. Views folder contains one folder for each controller and a "Shared" folder
3. Shared folder is used to store views shared between controllers. Master and Layout pages are stored in "Shared" folder.
Suggested Videos
Part 30 - View engines
Part 31 - Using custom view engines
Part 32 - How does a controller find a view
In this video, we will discuss
1. The purpose of html helpers
2. Some of the standard html helpers
What is an HTML helper?
An HTML helper is a method that is used to render html content in a view. HTML helpers are implemented as extension methods.
For example, to produce the HTML for a textbox with id="firstname" and name="firstname", we can type all the html in the view as shown below
<input type="text" name="firtsname" id="firstname" />
OR
We can use the "TextBox" html helper.
@Html.TextBox("firstname")
There are several overloaded versions. To set a value, along with the name, use the following overloaded version.
@Html.TextBox("firstname", "John")
The above html helper, generates the following HTML
<input id="firstname" name="firstname" type="text" value="John" />
To set HTML attributes, use the following overloaded version. Notice that, we are passing HTML attributes (style & title) as an anonymous type.
@Html.TextBox("firstname", "John", new { style = "background-color:Red; color:White; font-weight:bold", title="Please enter your first name" })
Some of the html attributes, are reserved keywords. Examples include class, readonly etc. To use these attributes, use "@" symbol as shown below.
@Html.TextBox("firstname", "John", new { @class = "redtextbox", @readonly="true" })
To generate a label for "First Name"
@Html.Label("fisrtname", "First Name")
To generate a textbox to enter password, so that the input is masked
@Html.Password("Password")
To generate a multi-line textbox with 5 rows and 20 columns
@Html.TextArea("Comments", "", 5, 20, null)
To generate a hidden textbox
@Html.Hidden("id")
Hidden textbox is used to store id values. Id values are not displayed on the page to the end user, but we need them to update data when the form is posted to the server.
Is it possible to create our own custom html helpers?
Yes, we will discuss this in a later video session.
Is it mandatory to use HTML helpers?
No, you can type the required HTML, but using HTML helpers will greatly reduce the amount of HTML that we have to write in a view. Views should be as simple as possible. All the complicated logic to generate a control can be encapsulated into the helper, to keep views simple.
Part 30 - View engines
Part 31 - Using custom view engines
Part 32 - How does a controller find a view
In this video, we will discuss
1. The purpose of html helpers
2. Some of the standard html helpers
What is an HTML helper?
An HTML helper is a method that is used to render html content in a view. HTML helpers are implemented as extension methods.
For example, to produce the HTML for a textbox with id="firstname" and name="firstname", we can type all the html in the view as shown below
<input type="text" name="firtsname" id="firstname" />
OR
We can use the "TextBox" html helper.
@Html.TextBox("firstname")
There are several overloaded versions. To set a value, along with the name, use the following overloaded version.
@Html.TextBox("firstname", "John")
The above html helper, generates the following HTML
<input id="firstname" name="firstname" type="text" value="John" />
To set HTML attributes, use the following overloaded version. Notice that, we are passing HTML attributes (style & title) as an anonymous type.
@Html.TextBox("firstname", "John", new { style = "background-color:Red; color:White; font-weight:bold", title="Please enter your first name" })
Some of the html attributes, are reserved keywords. Examples include class, readonly etc. To use these attributes, use "@" symbol as shown below.
@Html.TextBox("firstname", "John", new { @class = "redtextbox", @readonly="true" })
To generate a label for "First Name"
@Html.Label("fisrtname", "First Name")
To generate a textbox to enter password, so that the input is masked
@Html.Password("Password")
To generate a multi-line textbox with 5 rows and 20 columns
@Html.TextArea("Comments", "", 5, 20, null)
To generate a hidden textbox
@Html.Hidden("id")
Hidden textbox is used to store id values. Id values are not displayed on the page to the end user, but we need them to update data when the form is posted to the server.
Is it possible to create our own custom html helpers?
Yes, we will discuss this in a later video session.
Is it mandatory to use HTML helpers?
No, you can type the required HTML, but using HTML helpers will greatly reduce the amount of HTML that we have to write in a view. Views should be as simple as possible. All the complicated logic to generate a control can be encapsulated into the helper, to keep views simple.
Suggested Videos
Part 31 - Using custom view engines
Part 32 - How does a controller find a view
Part 33 - Html helpers
To generate a dropdownlist, use DropDownList html helper. A dropdownlist in MVC is a collection of SelectListItem objects. Depending on your project requirement you may either hard code the values in code or retrieve them from a database table. In this video, we will discuss both the approaches.
Generating a dropdownlist using hard coded values: We will use the following overloaded version of "DropDownList" html helper.
DropDownList(string name, IEnumerable<SelectListItem> selectList, string optionLabel)
The following code will generate a departments dropdown list. The first item in the list will be "Select Department".
@Html.DropDownList("Departments", new List<SelectListItem>
{
new SelectListItem { Text = "IT", Value = "1", Selected=true},
new SelectListItem { Text = "HR", Value = "2"},
new SelectListItem { Text = "Payroll", Value = "3"}
}, "Select Department")
The downside of hard coding dropdownlist values with-in code is that, if we have to add or remove departments from the dropdownlist, the code needs to be modified.
In most cases, we get values from the database table. For this example, let's use entity framework to retrieve data. Add ADO.NET entity data model. We discussed working with entity framework in Part 8 & Part 25.
To pass list of Departments from the controller, store them in "ViewBag"
public ActionResult Index()
{
// Connect to the database
SampleDBContext db = new SampleDBContext();
// Retrieve departments, and build SelectList
ViewBag.Departments = new SelectList(db.Departments, "Id", "Name");
return View();
}
Now in the "Index" view, access Departments list from "ViewBag"
@Html.DropDownList("Departments", "Select Department")
Part 31 - Using custom view engines
Part 32 - How does a controller find a view
Part 33 - Html helpers
To generate a dropdownlist, use DropDownList html helper. A dropdownlist in MVC is a collection of SelectListItem objects. Depending on your project requirement you may either hard code the values in code or retrieve them from a database table. In this video, we will discuss both the approaches.
Generating a dropdownlist using hard coded values: We will use the following overloaded version of "DropDownList" html helper.
DropDownList(string name, IEnumerable<SelectListItem> selectList, string optionLabel)
The following code will generate a departments dropdown list. The first item in the list will be "Select Department".
@Html.DropDownList("Departments", new List<SelectListItem>
{
new SelectListItem { Text = "IT", Value = "1", Selected=true},
new SelectListItem { Text = "HR", Value = "2"},
new SelectListItem { Text = "Payroll", Value = "3"}
}, "Select Department")
The downside of hard coding dropdownlist values with-in code is that, if we have to add or remove departments from the dropdownlist, the code needs to be modified.
In most cases, we get values from the database table. For this example, let's use entity framework to retrieve data. Add ADO.NET entity data model. We discussed working with entity framework in Part 8 & Part 25.
To pass list of Departments from the controller, store them in "ViewBag"
public ActionResult Index()
{
// Connect to the database
SampleDBContext db = new SampleDBContext();
// Retrieve departments, and build SelectList
ViewBag.Departments = new SelectList(db.Departments, "Id", "Name");
return View();
}
Now in the "Index" view, access Departments list from "ViewBag"
@Html.DropDownList("Departments", "Select Department")
Part 35 - Setting an item selected when an asp.net mvc dropdownlist is
loaded
Suggested Videos
Part 32 - How does a controller find a view
Part 33 - Html helpers
Part 34 - Generating a dropdownlist control in mvc using HTML helpers
In this video we will discuss, how to set an item selected when an asp.net mvc dropdownlist options are loaded from a database table. Please watch Part 34 before proceeding.
To have the "IT" department selected, when the departments are loaded from tblDepartment table, use the following overloaded constructor of "SelectList" class. Notice that we are passing a value of "1" for "selectedValue" parameter.
ViewBag.Departments = new SelectList(db.Departments, "Id", "Name", "1");
If you run the application at this point, "IT" department will be selected, when the dropdownlist is rendered. The downside of hard-coding the "selectedValue" in code is that, application code needs to be modified, if we want "HR" department to be selected instead of "IT". So every time there is a change in requirement, we need to change the application code.
Let's now discuss, the steps required to drive the selection of an item in the dropdownlist using a column in tblDepartment table.
Step 1: Add "IsSelected" bit column to tblDepartment table
ALTER TABLE tblDepartment
ADD IsSelected BIT
Step 2: At this point, this column will be null for all the rows in tblDepartment table. If we want IT department to be selected by default when the dropdownlist is loaded, set "IsSelected=1" for the "IT" department row.
Update tblDepartment Set IsSelected = 1 Where Id = 2
Step 3: Refresh ADO.NET Entity Data Model
Step 4: Finally, make the following changes to the "Index()" action method in "HomeController" class.
public ActionResult Index()
{
SampleDBContext db = new SampleDBContext();
List<SelectListItem> selectListItems = new List<SelectListItem>();
foreach (Department department in db.Departments)
{
SelectListItem selectListItem = new SelectListItem
{
Text = department.Name,
Value = department.Id.ToString(),
Selected = department.IsSelected.HasValue ? department.IsSelected.Value : false
};
selectListItems.Add(selectListItem);
}
ViewBag.Departments = selectListItems;
return View();
}
Run the application and notice that, "IT" department is selected, when the dropdownlist is loaded.
If you now want "HR" department to be selected, instead of "IT", set "IsSelected=1" for "HR" department and "IsSelected=0" for "IT" department.
Update tblDepartment Set IsSelected = 1 Where Id = 2
Update tblDepartment Set IsSelected = 0 Where Id = 1
Part 32 - How does a controller find a view
Part 33 - Html helpers
Part 34 - Generating a dropdownlist control in mvc using HTML helpers
In this video we will discuss, how to set an item selected when an asp.net mvc dropdownlist options are loaded from a database table. Please watch Part 34 before proceeding.
To have the "IT" department selected, when the departments are loaded from tblDepartment table, use the following overloaded constructor of "SelectList" class. Notice that we are passing a value of "1" for "selectedValue" parameter.
ViewBag.Departments = new SelectList(db.Departments, "Id", "Name", "1");
If you run the application at this point, "IT" department will be selected, when the dropdownlist is rendered. The downside of hard-coding the "selectedValue" in code is that, application code needs to be modified, if we want "HR" department to be selected instead of "IT". So every time there is a change in requirement, we need to change the application code.
Let's now discuss, the steps required to drive the selection of an item in the dropdownlist using a column in tblDepartment table.
Step 1: Add "IsSelected" bit column to tblDepartment table
ALTER TABLE tblDepartment
ADD IsSelected BIT
Step 2: At this point, this column will be null for all the rows in tblDepartment table. If we want IT department to be selected by default when the dropdownlist is loaded, set "IsSelected=1" for the "IT" department row.
Update tblDepartment Set IsSelected = 1 Where Id = 2
Step 3: Refresh ADO.NET Entity Data Model
Step 4: Finally, make the following changes to the "Index()" action method in "HomeController" class.
public ActionResult Index()
{
SampleDBContext db = new SampleDBContext();
List<SelectListItem> selectListItems = new List<SelectListItem>();
foreach (Department department in db.Departments)
{
SelectListItem selectListItem = new SelectListItem
{
Text = department.Name,
Value = department.Id.ToString(),
Selected = department.IsSelected.HasValue ? department.IsSelected.Value : false
};
selectListItems.Add(selectListItem);
}
ViewBag.Departments = selectListItems;
return View();
}
Run the application and notice that, "IT" department is selected, when the dropdownlist is loaded.
If you now want "HR" department to be selected, instead of "IT", set "IsSelected=1" for "HR" department and "IsSelected=0" for "IT" department.
Update tblDepartment Set IsSelected = 1 Where Id = 2
Update tblDepartment Set IsSelected = 0 Where Id = 1
Part 36 - Difference between Html.TextBox and Html.TextBoxFor
Suggested Videos
Part 33 - Html helpers
Part 34 - Generating a dropdownlist control in mvc using HTML helpers
Part 35 - How to set an item selected when dropdownlist is loaded
Let's understand the difference between TextBox and TextBoxFor & DropDownList and DropDownListFor HTML helpers with an example. Please watch Part 35, before proceeding.
Right click on the "Models" folder and add a class file with "name=Company.cs". Copy and paste the following code.
public class Company
{
private string _name;
public Company(string name)
{
this._name = name;
}
public List<Department> Departments
{
get
{
SampleDBContext db = new SampleDBContext();
return db.Departments.ToList();
}
}
public string CompanyName
{
get
{
return _name;
}
set
{
_name = value;
}
}
}
Copy and paste the following code in HomeController class. Notice that we are storing the "Departments" and "CompanyName" in the ViewBag object.
public ActionResult Index()
{
Company company = new Company("Pragim");
ViewBag.Departments = new SelectList(company.Departments, "Id", "Name");
ViewBag.CompanyName = company.CompanyName;
return View();
}
Right click on the "Index" action method in "HomeController" and add a view with "name=Index". Copy and paste the following code. Notice that, here the view is not strongly typed, and we are hard-coding the name for TextBox and DropDownList HTML helpers.
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
@Html.TextBox("CompanyName", (string)ViewBag.CompanyName)
<br />
@Html.DropDownList("Departments", "Select Department")
Add the following "Index1" action method to "HomeController". Notice that we are passing "Company" object to the View, and hence the view is strongly typed. Since the view is strongly typed, we can use TextBoxFor and DropDownListFor HTML helpers.
public ActionResult Index1()
{
Company company = new Company("Pragim");
return View(company);
}
Right click on the "Index1" action method in "HomeController" and add a view with "name=Index1". Copy and paste the following code.
@model MVCDemo.Models.Company
@{
ViewBag.Title = "Index1";
}
<h2>Index1</h2>
@Html.TextBoxFor(m => m.CompanyName)
<br />
@Html.DropDownListFor(m => m.Departments, new SelectList(Model.Departments, "Id", "Name"), "Select Department")
At this point, run the application and navigate to "http://localhost/MVCDemo/home/index". A textbox and a dropdownlist will be rendered. Right click on the page and view it's source. The generated HTML is as shown below.
<h2>Index</h2>
<input id="CompanyName" name="CompanyName" type="text" value="Test" />
<br />
<select id="Departments" name="Departments"><option value="">Select Department</option>
<option value="1">IT</option>
<option value="2">HR</option>
<option value="3">Payroll</option>
</select>
Now navigate to "http://localhost/MVCDemo/home/index1" and view page source. The HTML will be exactly the same as above.
So, in short, here are the differences
Html.TextBox amd Html.DropDownList are not strongly typed and hence they doesn't require a strongly typed view. This means that we can hardcode whatever name we want. On the other hand, Html.TextBoxFor and Html.DropDownListFor are strongly typed and requires a strongly typed view, and the name is inferred from the lambda expression.
Strongly typed HTML helpers also provide compile time checking.
Since, in real time, we mostly use strongly typed views, prefer to use Html.TextBoxFor and Html.DropDownListFor over their counterparts.
Whether, we use Html.TextBox & Html.DropDownList OR Html.TextBoxFor & Html.DropDownListFor, the end result is the same, that is they produce the same HTML.
Strongly typed HTML helpers are added in MVC2.
Part 33 - Html helpers
Part 34 - Generating a dropdownlist control in mvc using HTML helpers
Part 35 - How to set an item selected when dropdownlist is loaded
Let's understand the difference between TextBox and TextBoxFor & DropDownList and DropDownListFor HTML helpers with an example. Please watch Part 35, before proceeding.
Right click on the "Models" folder and add a class file with "name=Company.cs". Copy and paste the following code.
public class Company
{
private string _name;
public Company(string name)
{
this._name = name;
}
public List<Department> Departments
{
get
{
SampleDBContext db = new SampleDBContext();
return db.Departments.ToList();
}
}
public string CompanyName
{
get
{
return _name;
}
set
{
_name = value;
}
}
}
Copy and paste the following code in HomeController class. Notice that we are storing the "Departments" and "CompanyName" in the ViewBag object.
public ActionResult Index()
{
Company company = new Company("Pragim");
ViewBag.Departments = new SelectList(company.Departments, "Id", "Name");
ViewBag.CompanyName = company.CompanyName;
return View();
}
Right click on the "Index" action method in "HomeController" and add a view with "name=Index". Copy and paste the following code. Notice that, here the view is not strongly typed, and we are hard-coding the name for TextBox and DropDownList HTML helpers.
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
@Html.TextBox("CompanyName", (string)ViewBag.CompanyName)
<br />
@Html.DropDownList("Departments", "Select Department")
Add the following "Index1" action method to "HomeController". Notice that we are passing "Company" object to the View, and hence the view is strongly typed. Since the view is strongly typed, we can use TextBoxFor and DropDownListFor HTML helpers.
public ActionResult Index1()
{
Company company = new Company("Pragim");
return View(company);
}
Right click on the "Index1" action method in "HomeController" and add a view with "name=Index1". Copy and paste the following code.
@model MVCDemo.Models.Company
@{
ViewBag.Title = "Index1";
}
<h2>Index1</h2>
@Html.TextBoxFor(m => m.CompanyName)
<br />
@Html.DropDownListFor(m => m.Departments, new SelectList(Model.Departments, "Id", "Name"), "Select Department")
At this point, run the application and navigate to "http://localhost/MVCDemo/home/index". A textbox and a dropdownlist will be rendered. Right click on the page and view it's source. The generated HTML is as shown below.
<h2>Index</h2>
<input id="CompanyName" name="CompanyName" type="text" value="Test" />
<br />
<select id="Departments" name="Departments"><option value="">Select Department</option>
<option value="1">IT</option>
<option value="2">HR</option>
<option value="3">Payroll</option>
</select>
Now navigate to "http://localhost/MVCDemo/home/index1" and view page source. The HTML will be exactly the same as above.
So, in short, here are the differences
Html.TextBox amd Html.DropDownList are not strongly typed and hence they doesn't require a strongly typed view. This means that we can hardcode whatever name we want. On the other hand, Html.TextBoxFor and Html.DropDownListFor are strongly typed and requires a strongly typed view, and the name is inferred from the lambda expression.
Strongly typed HTML helpers also provide compile time checking.
Since, in real time, we mostly use strongly typed views, prefer to use Html.TextBoxFor and Html.DropDownListFor over their counterparts.
Whether, we use Html.TextBox & Html.DropDownList OR Html.TextBoxFor & Html.DropDownListFor, the end result is the same, that is they produce the same HTML.
Strongly typed HTML helpers are added in MVC2.
Suggested Videos
Part 34 - Generating a dropdownlist control in mvc using HTML helpers
Part 35 - How to set an item selected when dropdownlist is loaded
Part 36 - Difference between Html.TextBox and Html.TextBoxFor
In this video, we will discuss, generating a radiobuttonlist in mvc using Html.RadioButtonFor helper. Please watch Part 36 before proceeding.
Right click on the "Models" folder and add a class file with "name=Company.cs". Copy and paste the following code.
public class Company
{
public string SelectedDepartment { get; set; }
public List<Department> Departments
{
get
{
SampleDBContext db = new SampleDBContext();
return db.Departments.ToList();
}
}
}
Copy and paste the following 2 "Index" action methods in HomeController class.
[HttpGet]
public ActionResult Index()
{
Company company = new Company();
return View(company);
}
[HttpPost]
public string Index(Company company)
{
if (string.IsNullOrEmpty(company.SelectedDepartment))
{
return "You did not select any department";
}
else
{
return "You selected department with ID = " + company.SelectedDepartment;
}
}
Right click on the "Index" action method in "HomeController" and add a view with "name=Index". Copy and paste the following code.
@model MVCDemo.Models.Company
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
@using (Html.BeginForm())
{
foreach (var department in Model.Departments)
{
@Html.RadioButtonFor(m => m.SelectedDepartment, department.Id) @department.Name
}
<br />
<br />
<input type="submit" value="Submit" />
}
Run the application and click on "Submit" without selecting any department. Notice that, you get a message stating you have not selected any department. On the other hand, select a department and click "Submit". The selected department ID must be displayed.
Part 34 - Generating a dropdownlist control in mvc using HTML helpers
Part 35 - How to set an item selected when dropdownlist is loaded
Part 36 - Difference between Html.TextBox and Html.TextBoxFor
In this video, we will discuss, generating a radiobuttonlist in mvc using Html.RadioButtonFor helper. Please watch Part 36 before proceeding.
Right click on the "Models" folder and add a class file with "name=Company.cs". Copy and paste the following code.
public class Company
{
public string SelectedDepartment { get; set; }
public List<Department> Departments
{
get
{
SampleDBContext db = new SampleDBContext();
return db.Departments.ToList();
}
}
}
Copy and paste the following 2 "Index" action methods in HomeController class.
[HttpGet]
public ActionResult Index()
{
Company company = new Company();
return View(company);
}
[HttpPost]
public string Index(Company company)
{
if (string.IsNullOrEmpty(company.SelectedDepartment))
{
return "You did not select any department";
}
else
{
return "You selected department with ID = " + company.SelectedDepartment;
}
}
Right click on the "Index" action method in "HomeController" and add a view with "name=Index". Copy and paste the following code.
@model MVCDemo.Models.Company
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
@using (Html.BeginForm())
{
foreach (var department in Model.Departments)
{
@Html.RadioButtonFor(m => m.SelectedDepartment, department.Id) @department.Name
}
<br />
<br />
<input type="submit" value="Submit" />
}
Run the application and click on "Submit" without selecting any department. Notice that, you get a message stating you have not selected any department. On the other hand, select a department and click "Submit". The selected department ID must be displayed.
Part 38 - CheckBoxList in asp.net mvc
Suggested Videos
Part 35 - How to set an item selected when dropdownlist is loaded
Part 36 - Difference between Html.TextBox and Html.TextBoxFor
Part 37 - Generating a radiobuttonlist control in mvc using HTML helpers
In this video we will discuss implementing a checkbox list in asp.net mvc. We will be using table "tblCity" for this demo.

We should be generating a checkbox for each city from the table tblCity.

Sql script to create table tblCity
CREATE TABLE tblCity
(
ID INT IDENTITY PRIMARY KEY,
Name NVARCHAR(100) NOT NULL,
IsSelected BIT NOT NULL
)
Insert into tblCity values ('London', 0)
Insert into tblCity values ('New York', 0)
Insert into tblCity values ('Sydney', 1)
Insert into tblCity values ('Mumbai', 0)
Insert into tblCity values ('Cambridge', 0)
Let's add ADO.NET data model, to retrieve data from database
1. Right click on the "Models" folder > Add > Add New Item
2. From "Add New Item" dialog box, select "ADO.NET Entity Data Model"
3. Set Name=SampleDataModel.edmx and click "Add"
4. On "Entity Data Model" wizard, select "Generate from database" and click "Next"
5. Check "Save entity connection settings in Web.Config as:" checkbox
6. Type "SampleDBContext" as the connection string name and click "Next"
7. On "Choose Your Database Objects" screen, expand "Tables" and select "tblCity" table
8. Type "Models" in "Model Namespace" textbox and click "Finish"
9. Change the entity name from "tblCity" to "City"

Right click on the "Controllers" folder, and add a "HomeController". Include the following 2 namespaces in "HomeController"
using MVCDemo.Models;
using System.Text;
Copy and paste the following code.
[HttpGet]
public ActionResult Index()
{
SampleDBContext db = new SampleDBContext();
return View(db.Cities);
}
[HttpPost]
public string Index(IEnumerable<City> cities)
{
if (cities.Count(x => x.IsSelected) == 0)
{
return "You have not selected any City";
}
else
{
StringBuilder sb = new StringBuilder();
sb.Append("You selected - ");
foreach (City city in cities)
{
if (city.IsSelected)
{
sb.Append(city.Name + ", ");
}
}
sb.Remove(sb.ToString().LastIndexOf(","), 1);
return sb.ToString();
}
}
Right click on the "Views" folder, and a "Home" folder. Right click on the "Home" folder and "EditorTemplates" folder.
Right click on "EditorTemplates" folder > Add > View. In the "Add View" dialog box, set
View Name = City
View Engine = Razor
and click "Add".
Copy and paste the following code in "City.cshtml"
@model MVCDemo.Models.City
@{
ViewBag.Title = "City";
}
@Html.HiddenFor(x => x.ID)
@Html.HiddenFor(x => x.Name)
@Html.CheckBoxFor(x => x.IsSelected)
@Html.DisplayFor(x => x.Name)
Please Note: Put the templates in "Shared" folder, if you want the "Templates", to be available for all the views.
Right click on the "Index" action method in "HomeController", and select "Add View" from the contex menu. Set
View Name = Index
View Engine = Razor and click "Add"
Copy and paste the following code in "Index.cshtml"
@model IEnumerable<MVCDemo.Models.City>
@{
ViewBag.Title = "Index";
}
<div style="font-family:Arial">
<h2>Index</h2>
@using (Html.BeginForm())
{
@Html.EditorForModel()
<br />
<input type="submit" value="Submit" />
}
</div>
Part 35 - How to set an item selected when dropdownlist is loaded
Part 36 - Difference between Html.TextBox and Html.TextBoxFor
Part 37 - Generating a radiobuttonlist control in mvc using HTML helpers
In this video we will discuss implementing a checkbox list in asp.net mvc. We will be using table "tblCity" for this demo.

We should be generating a checkbox for each city from the table tblCity.

Sql script to create table tblCity
CREATE TABLE tblCity
(
ID INT IDENTITY PRIMARY KEY,
Name NVARCHAR(100) NOT NULL,
IsSelected BIT NOT NULL
)
Insert into tblCity values ('London', 0)
Insert into tblCity values ('New York', 0)
Insert into tblCity values ('Sydney', 1)
Insert into tblCity values ('Mumbai', 0)
Insert into tblCity values ('Cambridge', 0)
Let's add ADO.NET data model, to retrieve data from database
1. Right click on the "Models" folder > Add > Add New Item
2. From "Add New Item" dialog box, select "ADO.NET Entity Data Model"
3. Set Name=SampleDataModel.edmx and click "Add"
4. On "Entity Data Model" wizard, select "Generate from database" and click "Next"
5. Check "Save entity connection settings in Web.Config as:" checkbox
6. Type "SampleDBContext" as the connection string name and click "Next"
7. On "Choose Your Database Objects" screen, expand "Tables" and select "tblCity" table
8. Type "Models" in "Model Namespace" textbox and click "Finish"
9. Change the entity name from "tblCity" to "City"

Right click on the "Controllers" folder, and add a "HomeController". Include the following 2 namespaces in "HomeController"
using MVCDemo.Models;
using System.Text;
Copy and paste the following code.
[HttpGet]
public ActionResult Index()
{
SampleDBContext db = new SampleDBContext();
return View(db.Cities);
}
[HttpPost]
public string Index(IEnumerable<City> cities)
{
if (cities.Count(x => x.IsSelected) == 0)
{
return "You have not selected any City";
}
else
{
StringBuilder sb = new StringBuilder();
sb.Append("You selected - ");
foreach (City city in cities)
{
if (city.IsSelected)
{
sb.Append(city.Name + ", ");
}
}
sb.Remove(sb.ToString().LastIndexOf(","), 1);
return sb.ToString();
}
}
Right click on the "Views" folder, and a "Home" folder. Right click on the "Home" folder and "EditorTemplates" folder.
Right click on "EditorTemplates" folder > Add > View. In the "Add View" dialog box, set
View Name = City
View Engine = Razor
and click "Add".
Copy and paste the following code in "City.cshtml"
@model MVCDemo.Models.City
@{
ViewBag.Title = "City";
}
@Html.HiddenFor(x => x.ID)
@Html.HiddenFor(x => x.Name)
@Html.CheckBoxFor(x => x.IsSelected)
@Html.DisplayFor(x => x.Name)
Please Note: Put the templates in "Shared" folder, if you want the "Templates", to be available for all the views.
Right click on the "Index" action method in "HomeController", and select "Add View" from the contex menu. Set
View Name = Index
View Engine = Razor and click "Add"
Copy and paste the following code in "Index.cshtml"
@model IEnumerable<MVCDemo.Models.City>
@{
ViewBag.Title = "Index";
}
<div style="font-family:Arial">
<h2>Index</h2>
@using (Html.BeginForm())
{
@Html.EditorForModel()
<br />
<input type="submit" value="Submit" />
}
</div>
Part 39 - ListBox in asp.net mvc
Suggested Videos
Part 36 - Difference between Html.TextBox and Html.TextBoxFor
Part 37 - Generating a radiobuttonlist control in mvc using HTML helpers
Part 38 - CheckBoxList in asp.net mvc
In this video we will discuss implementing ListBox in asp.net mvc. We will be using table "tblCity" for this demo.

Please refer to Part 38, if you need the sql script to create and populate this table. Please watch Part 38, before proceeding.
The generated listbox should be as shown below. Notice that for each city in table "tblCity", there is an entry in the listbox.

For this demo, we will be using the "City" entity that we generated using ADO.NET entity framework, in Part 38.

The first step is to create a ViewModel class. In asp.net mvc, view model's are used as techniques to shuttle data between the controller and the view. Right click on the "Models" folder, and add a class file with name=CitiesViewModel.cs. Copy and paste the following code. This class is going to be the Model for the view.
public class CitiesViewModel
{
public IEnumerable<string> SelectedCities { get; set; }
public IEnumerable<SelectListItem> Cities { get; set; }
}
Right click on the "Controllers" folder, and add a "HomeController". Include the following 2 namespaces in "HomeController"
using MVCDemo.Models;
using System.Text;
Copy and paste the following code.
[HttpGet]
public ActionResult Index()
{
SampleDBContext db = new SampleDBContext();
List<SelectListItem> listSelectListItems = new List<SelectListItem>();
foreach (City city in db.Cities)
{
SelectListItem selectList = new SelectListItem()
{
Text = city.Name,
Value = city.ID.ToString(),
Selected = city.IsSelected
};
listSelectListItems.Add(selectList);
}
CitiesViewModel citiesViewModel = new CitiesViewModel()
{
Cities = listSelectListItems
};
return View(citiesViewModel);
}
[HttpPost]
public string Index(IEnumerable<string> selectedCities)
{
if (selectedCities == null)
{
return "No cities selected";
}
else
{
StringBuilder sb = new StringBuilder();
sb.Append("You selected - " + string.Join(",", selectedCities));
return sb.ToString();
}
}
Right click on the "Index" action method in "HomeController" and select "Add View" from the context menu. Set
View Name = Index
View Engine = Razor
and click "Add".
Copy and paste the following code in "Index.cshtml"
@model MVCDemo.Models.CitiesViewModel
@{
ViewBag.Title = "Index";
}
<div style="font-family:Arial">
<h2>Index</h2>
@using (Html.BeginForm())
{
@Html.ListBoxFor(m => m.SelectedCities, Model.Cities, new { size = 4 })
<br />
<input type="submit" value="Submit" />
}
</div>
Note: To select multiple items from the listbox, hold down the CTRL Key.
Part 36 - Difference between Html.TextBox and Html.TextBoxFor
Part 37 - Generating a radiobuttonlist control in mvc using HTML helpers
Part 38 - CheckBoxList in asp.net mvc
In this video we will discuss implementing ListBox in asp.net mvc. We will be using table "tblCity" for this demo.

Please refer to Part 38, if you need the sql script to create and populate this table. Please watch Part 38, before proceeding.
The generated listbox should be as shown below. Notice that for each city in table "tblCity", there is an entry in the listbox.

For this demo, we will be using the "City" entity that we generated using ADO.NET entity framework, in Part 38.

The first step is to create a ViewModel class. In asp.net mvc, view model's are used as techniques to shuttle data between the controller and the view. Right click on the "Models" folder, and add a class file with name=CitiesViewModel.cs. Copy and paste the following code. This class is going to be the Model for the view.
public class CitiesViewModel
{
public IEnumerable<string> SelectedCities { get; set; }
public IEnumerable<SelectListItem> Cities { get; set; }
}
Right click on the "Controllers" folder, and add a "HomeController". Include the following 2 namespaces in "HomeController"
using MVCDemo.Models;
using System.Text;
Copy and paste the following code.
[HttpGet]
public ActionResult Index()
{
SampleDBContext db = new SampleDBContext();
List<SelectListItem> listSelectListItems = new List<SelectListItem>();
foreach (City city in db.Cities)
{
SelectListItem selectList = new SelectListItem()
{
Text = city.Name,
Value = city.ID.ToString(),
Selected = city.IsSelected
};
listSelectListItems.Add(selectList);
}
CitiesViewModel citiesViewModel = new CitiesViewModel()
{
Cities = listSelectListItems
};
return View(citiesViewModel);
}
[HttpPost]
public string Index(IEnumerable<string> selectedCities)
{
if (selectedCities == null)
{
return "No cities selected";
}
else
{
StringBuilder sb = new StringBuilder();
sb.Append("You selected - " + string.Join(",", selectedCities));
return sb.ToString();
}
}
Right click on the "Index" action method in "HomeController" and select "Add View" from the context menu. Set
View Name = Index
View Engine = Razor
and click "Add".
Copy and paste the following code in "Index.cshtml"
@model MVCDemo.Models.CitiesViewModel
@{
ViewBag.Title = "Index";
}
<div style="font-family:Arial">
<h2>Index</h2>
@using (Html.BeginForm())
{
@Html.ListBoxFor(m => m.SelectedCities, Model.Cities, new { size = 4 })
<br />
<input type="submit" value="Submit" />
}
</div>
Note: To select multiple items from the listbox, hold down the CTRL Key.
Suggested Videos
Part 37 - Generating a radiobuttonlist control in mvc using HTML helpers
Part 38 - CheckBoxList in asp.net mvc
Part 39 - ListBox in asp.net mvc
In this video, we will discuss using the following attributes, with examples.
1. Display
2. DisplayName
3. DisplayFormat
4. ScaffoldColumn
We will be using table tblEmployee for this demo.
Create table tblEmployee
(
Id int primary key identity,
FullName nvarchar(100),
Gender nvarchar(10),
Age int,
HireDate DateTime,
EmailAddress nvarchar(100),
Salary int,
PersonalWebSite nvarchar(100)
)
Insert into tblEmployee values
('John Smith', 'Male', 35, '2007-01-02 17:53:46.833', 'JohnSmith@pragimtech.com', 45000, 'http://www.pragimtech.com')
Insert into tblEmployee values
('Mary Jane', NULL, 30, '2009-05-02 19:43:25.965', 'MaryJane@pragimtech.com', 35000, 'http://www.pragimtech.com')
Generate ADO.NET entity data model for table tblEmployee. Change the entity name from tblEmployee to Employee. Save and build the project.
Right click on the "Controllers" folder and add "HomeController". Include the following "USING" statement.
using MVCDemo.Models;
Copy and paste the following code.
public class HomeController : Controller
{
public ActionResult Details(int id)
{
SampleDBContext db = new SampleDBContext();
Employee employee = db.Employees.Single(x => x.Id == id);
return View(employee);
}
}
Right click on the "Details" action method, and add "Details" view. Make sure you are creating a strongly typed view against "Employee" class. Select "Details" as the "Scaffold Template". Run the application and notice that, the output is not that pretty.
We can control the display of data in a view using display attributes that are found in System.ComponentModel.DataAnnotations namespace. It is not a good idea, to add display attributes to the properties of auto-generated "Employee" class, as our changes will be lost, if the class is auto-generated again.
So, let's create another partial "Employee" class, and decorate that class with the display attributes. Right click on the "Models" folder and add Employee.cs class file. Copy and paste the following code.
namespace MVCDemo.Models
{
[MetadataType(typeof(EmployeeMetaData))]
public partial class Employee
{
}
public class EmployeeMetaData
{
//If you want "FullName" to be displayed as "Full Name",
//use DisplayAttribute or DisplayName attribute.
//DisplayName attribute is in System.ComponentModel namespace.
//[DisplayAttribute(Name="Full Name")]
//[Display(Name = "Full Name")]
[DisplayName("Full Name")]
public string FullName { get; set; }
//To get only the date part in a datetime data type
//[DisplayFormat(DataFormatString = "{0:d}")]
//[DisplayFormatAttribute(DataFormatString="{0:d}")]
//To get time in 24 hour notation
//[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy HH:mm:ss}")]
//To get time in 12 hour notation with AM PM
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy hh:mm:ss tt}")]
public DateTime? HireDate { get; set; }
// If gender is NULL, "Gender not specified" text will be displayed.
[DisplayFormat(NullDisplayText = "Gender not specified")]
public string Gender { get; set; }
//If you don't want to display a column use ScaffoldColumn attribute.
//This only works when you use @Html.DisplayForModel() helper
[ScaffoldColumn(false)]
public int? Salary { get; set; }
}
}
Make sure to include the following using statements:
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
We will discuss the following attributes in our next video session.
DataTypeAttribute,
DisplayColumnAttribute
Part 37 - Generating a radiobuttonlist control in mvc using HTML helpers
Part 38 - CheckBoxList in asp.net mvc
Part 39 - ListBox in asp.net mvc
In this video, we will discuss using the following attributes, with examples.
1. Display
2. DisplayName
3. DisplayFormat
4. ScaffoldColumn
We will be using table tblEmployee for this demo.
Create table tblEmployee
(
Id int primary key identity,
FullName nvarchar(100),
Gender nvarchar(10),
Age int,
HireDate DateTime,
EmailAddress nvarchar(100),
Salary int,
PersonalWebSite nvarchar(100)
)
Insert into tblEmployee values
('John Smith', 'Male', 35, '2007-01-02 17:53:46.833', 'JohnSmith@pragimtech.com', 45000, 'http://www.pragimtech.com')
Insert into tblEmployee values
('Mary Jane', NULL, 30, '2009-05-02 19:43:25.965', 'MaryJane@pragimtech.com', 35000, 'http://www.pragimtech.com')
Generate ADO.NET entity data model for table tblEmployee. Change the entity name from tblEmployee to Employee. Save and build the project.
Right click on the "Controllers" folder and add "HomeController". Include the following "USING" statement.
using MVCDemo.Models;
Copy and paste the following code.
public class HomeController : Controller
{
public ActionResult Details(int id)
{
SampleDBContext db = new SampleDBContext();
Employee employee = db.Employees.Single(x => x.Id == id);
return View(employee);
}
}
Right click on the "Details" action method, and add "Details" view. Make sure you are creating a strongly typed view against "Employee" class. Select "Details" as the "Scaffold Template". Run the application and notice that, the output is not that pretty.
We can control the display of data in a view using display attributes that are found in System.ComponentModel.DataAnnotations namespace. It is not a good idea, to add display attributes to the properties of auto-generated "Employee" class, as our changes will be lost, if the class is auto-generated again.
So, let's create another partial "Employee" class, and decorate that class with the display attributes. Right click on the "Models" folder and add Employee.cs class file. Copy and paste the following code.
namespace MVCDemo.Models
{
[MetadataType(typeof(EmployeeMetaData))]
public partial class Employee
{
}
public class EmployeeMetaData
{
//If you want "FullName" to be displayed as "Full Name",
//use DisplayAttribute or DisplayName attribute.
//DisplayName attribute is in System.ComponentModel namespace.
//[DisplayAttribute(Name="Full Name")]
//[Display(Name = "Full Name")]
[DisplayName("Full Name")]
public string FullName { get; set; }
//To get only the date part in a datetime data type
//[DisplayFormat(DataFormatString = "{0:d}")]
//[DisplayFormatAttribute(DataFormatString="{0:d}")]
//To get time in 24 hour notation
//[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy HH:mm:ss}")]
//To get time in 12 hour notation with AM PM
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy hh:mm:ss tt}")]
public DateTime? HireDate { get; set; }
// If gender is NULL, "Gender not specified" text will be displayed.
[DisplayFormat(NullDisplayText = "Gender not specified")]
public string Gender { get; set; }
//If you don't want to display a column use ScaffoldColumn attribute.
//This only works when you use @Html.DisplayForModel() helper
[ScaffoldColumn(false)]
public int? Salary { get; set; }
}
}
Make sure to include the following using statements:
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
We will discuss the following attributes in our next video session.
DataTypeAttribute,
DisplayColumnAttribute
Suggested Videos
Part 38 - CheckBoxList in asp.net mvc
Part 39 - ListBox in asp.net mvc
Part 40 - Using displayname, displayformat, & scaffoldcolumn attributes
In this video, we will discuss using datatype and displaycolumn attributes. Please watch Part 40, before proceeding.
To understand DataType attribute, we will be using the same example, we used in Part 40. Copy and paste the following code in "Employee" class, and navigate to localhost/MVCDemo/Home/Details/1.
[MetadataType(typeof(EmployeeMetaData))]
public partial class Employee
{
}
public class EmployeeMetaData
{
// Display mailto hyperlink
[DataType(DataType.EmailAddress)]
public string EmailAddress { get; set; }
// Display currency symbol. For country specific currency, set
// culture using globalization element in web.config.
// For Great Britain Pound symbol
// <globalization culture="en-gb"/>
[DataType(DataType.Currency)]
public int? Salary { get; set; }
// Generate a hyperlink
[DataType(DataType.Url)]
public string PersonalWebSite { get; set; }
// Display only Time Part
// [DataType(DataType.Time)]
// Display only Date Part
[DataType(DataType.Date)]
public DateTime? HireDate { get; set; }
}
DisplayColumn attribute is useful, when a class has a property of complex type, and you want to pick one property of this complex object for display purpose. Let's understand this with an example.
Right click on the "Models" folder and add Company.cs class file. Copy and paste the following code.
public class Company
{
public Employee CompanyDirector
{
get
{
SampleDBContext db = new SampleDBContext();
return db.Employees.Single(x => x.Id == 1);
}
}
}
Notice that, this class has CompanyDirector property which returns an Employee object. Employee is a complex type. Employee object has got several properties. If you want FullName to be used for display purpose, then make the following changes.
Decorate "Employee" partial class in "Models" folder, with DisplayColumn attribute.
[MetadataType(typeof(EmployeeMetaData))]
[DisplayColumn("FullName")]
public partial class Employee
{
}
Change "Details" action method in "Home" controller as shown below.
public ActionResult Details(int id)
{
Company company = new Company();
return View(company);
}
Copy and paste the following code in Details.cshtml view
@model MVCDemo.Models.Company
@{
ViewBag.Title = "Details";
}
@Html.DisplayTextFor(x => x.CompanyDirector)
Navigate to localhost/MVCDemo/Home/Details/1 and you should see the FullName of the employee.
Part 38 - CheckBoxList in asp.net mvc
Part 39 - ListBox in asp.net mvc
Part 40 - Using displayname, displayformat, & scaffoldcolumn attributes
In this video, we will discuss using datatype and displaycolumn attributes. Please watch Part 40, before proceeding.
To understand DataType attribute, we will be using the same example, we used in Part 40. Copy and paste the following code in "Employee" class, and navigate to localhost/MVCDemo/Home/Details/1.
[MetadataType(typeof(EmployeeMetaData))]
public partial class Employee
{
}
public class EmployeeMetaData
{
// Display mailto hyperlink
[DataType(DataType.EmailAddress)]
public string EmailAddress { get; set; }
// Display currency symbol. For country specific currency, set
// culture using globalization element in web.config.
// For Great Britain Pound symbol
// <globalization culture="en-gb"/>
[DataType(DataType.Currency)]
public int? Salary { get; set; }
// Generate a hyperlink
[DataType(DataType.Url)]
public string PersonalWebSite { get; set; }
// Display only Time Part
// [DataType(DataType.Time)]
// Display only Date Part
[DataType(DataType.Date)]
public DateTime? HireDate { get; set; }
}
DisplayColumn attribute is useful, when a class has a property of complex type, and you want to pick one property of this complex object for display purpose. Let's understand this with an example.
Right click on the "Models" folder and add Company.cs class file. Copy and paste the following code.
public class Company
{
public Employee CompanyDirector
{
get
{
SampleDBContext db = new SampleDBContext();
return db.Employees.Single(x => x.Id == 1);
}
}
}
Notice that, this class has CompanyDirector property which returns an Employee object. Employee is a complex type. Employee object has got several properties. If you want FullName to be used for display purpose, then make the following changes.
Decorate "Employee" partial class in "Models" folder, with DisplayColumn attribute.
[MetadataType(typeof(EmployeeMetaData))]
[DisplayColumn("FullName")]
public partial class Employee
{
}
Change "Details" action method in "Home" controller as shown below.
public ActionResult Details(int id)
{
Company company = new Company();
return View(company);
}
Copy and paste the following code in Details.cshtml view
@model MVCDemo.Models.Company
@{
ViewBag.Title = "Details";
}
@Html.DisplayTextFor(x => x.CompanyDirector)
Navigate to localhost/MVCDemo/Home/Details/1 and you should see the FullName of the employee.
Suggested Videos
Part 39 - ListBox in asp.net mvc
Part 40 - Using displayname, displayformat, & scaffoldcolumn attributes
Part 41 - Using datatype and displaycolumn attributes
In this video, we will discuss opening URL's in a new window. Along the way, we also discuss using UIHint attribute. Please watch Part 41, before proceeding. We will be using the same example that we started in Part 40 of this video series.
Changes to Employee.cs class file in Models folder
[MetadataType(typeof(EmployeeMetaData))]
public partial class Employee
{
}
public class EmployeeMetaData
{
[DataType(DataType.Url)]
public string PersonalWebSite { get; set; }
}
Details action method in HomeController
public ActionResult Details(int id)
{
SampleDBContext db = new SampleDBContext();
Employee employee = db.Employees.Single(x => x.Id == id);
return View(employee);
}
Code in Details.cshtml view
@model MVCDemo.Models.Employee
@{
ViewBag.Title = "Details";
}
@Html.DisplayForModel()
At this point, buid the application and navigate to localhost/MVCDemo/Home/Details/1. When you click on the personal website link, the target page will open in the same window.
If you want the page to open in a new window,
1. Right click on "Views" folder, and add "Shared" folder.
2. Right click on "Shared" folder, and add "DisplayTemplates" folder.
3. Right click on DisplayTemplates folder, and add a view. Set "Url" as the name and use Razor view engine.
4. Copy and paste the following code in Url.cshtml view
<a href="@ViewData.Model" target="_blank">@ViewData.Model</a>
That's it. Build the application and click on the link. Notice that, the page, now opens in a new window. The downside of this approach is that, from now on all the links, will open in a new window. To overcome this, follow these steps.
1. Rename Url.cshtml to OpenInNewWindow.cshtml
2. Decorate "PersonalWebSite" property in EmployeeMetaData class with UIHint attribute and specify the name of the template to use. In our case, the name of the template is "OpenInNewWindow".
public class EmployeeMetaData
{
[DataType(DataType.Url)]
[UIHint("OpenInNewWindow")]
public string PersonalWebSite { get; set; }
}
So, UIHint attribute is used to specify the name of the template to use to display the data field.
Part 39 - ListBox in asp.net mvc
Part 40 - Using displayname, displayformat, & scaffoldcolumn attributes
Part 41 - Using datatype and displaycolumn attributes
In this video, we will discuss opening URL's in a new window. Along the way, we also discuss using UIHint attribute. Please watch Part 41, before proceeding. We will be using the same example that we started in Part 40 of this video series.
Changes to Employee.cs class file in Models folder
[MetadataType(typeof(EmployeeMetaData))]
public partial class Employee
{
}
public class EmployeeMetaData
{
[DataType(DataType.Url)]
public string PersonalWebSite { get; set; }
}
Details action method in HomeController
public ActionResult Details(int id)
{
SampleDBContext db = new SampleDBContext();
Employee employee = db.Employees.Single(x => x.Id == id);
return View(employee);
}
Code in Details.cshtml view
@model MVCDemo.Models.Employee
@{
ViewBag.Title = "Details";
}
@Html.DisplayForModel()
At this point, buid the application and navigate to localhost/MVCDemo/Home/Details/1. When you click on the personal website link, the target page will open in the same window.
If you want the page to open in a new window,
1. Right click on "Views" folder, and add "Shared" folder.
2. Right click on "Shared" folder, and add "DisplayTemplates" folder.
3. Right click on DisplayTemplates folder, and add a view. Set "Url" as the name and use Razor view engine.
4. Copy and paste the following code in Url.cshtml view
<a href="@ViewData.Model" target="_blank">@ViewData.Model</a>
That's it. Build the application and click on the link. Notice that, the page, now opens in a new window. The downside of this approach is that, from now on all the links, will open in a new window. To overcome this, follow these steps.
1. Rename Url.cshtml to OpenInNewWindow.cshtml
2. Decorate "PersonalWebSite" property in EmployeeMetaData class with UIHint attribute and specify the name of the template to use. In our case, the name of the template is "OpenInNewWindow".
public class EmployeeMetaData
{
[DataType(DataType.Url)]
[UIHint("OpenInNewWindow")]
public string PersonalWebSite { get; set; }
}
So, UIHint attribute is used to specify the name of the template to use to display the data field.
Suggested Videos
Part 40 - Using displayname, displayformat, & scaffoldcolumn attributes
Part 41 - Using datatype and displaycolumn attributes
Part 42 - Opening a page in new browser window in mvc
HiddenInput attribute is useful when you want to render a property using input type=hidden. This attribute is extremely useful, when you don't want the user to see or edit the property, but you need to post the property value to the server when the form is submitted, so the correct record can be updated. HiddenInput is present in System.Web.Mvc namespace.
ReadOnly attribute is present in System.ComponentModel namespace. As the name suggests, this attribute is used to make a property readonly. Please note that, we will still be able to change the property value on the view, but once we post the form the model binder will respect the readonly attribute and will not move the value to the property. You can also, make property of a class readonly simply, by removing the SET accessor.
Changes to Employee.cs file used in the demo. Notice that Id property is decorated with HiddenInput attribute, and EmailAddress is decorated with ReadOnly attribute.
public class EmployeeMetadata
{
// Id property is hidden and cannot be changed
[HiddenInput(DisplayValue=false)]
public int Id { get; set; }
// EmailAddress is read only
[ReadOnly(true)]
[DataType(DataType.EmailAddress)]
public string EmailAddress { get; set; }
[ScaffoldColumn(true)]
[DataType(DataType.Currency)]
public int? Salary { get; set; }
[DataType(DataType.Url)]
[UIHint("OpenInNewWindow")]
public string PersonalWebSite { get; set; }
[DisplayAttribute(Name= "Full Name")]
public string FullName { get; set; }
[DisplayFormat(DataFormatString="{0:d}")]
public DateTime? HireDate { get; set; }
[DisplayFormat(NullDisplayText="Gender not specified")]
public string Gender { get; set; }
}
Changes to HomeController.cs file
public ActionResult Edit(int id)
{
SampleDBContext db = new SampleDBContext();
Employee employee = db.Employees.Single(x => x.Id == id);
return View(employee);
}
[HttpPost]
public ActionResult Edit(Employee employee)
{
if (ModelState.IsValid)
{
SampleDBContext db = new SampleDBContext();
Employee employeeFromDB = db.Employees.Single(x => x.Id == employee.Id);
// Populate all the properties except EmailAddrees
employeeFromDB.FullName = employee.FullName;
employeeFromDB.Gender = employee.Gender;
employeeFromDB.Age = employee.Age;
employeeFromDB.HireDate = employee.HireDate;
employeeFromDB.Salary = employee.Salary;
employeeFromDB.PersonalWebSite = employee.PersonalWebSite;
db.ObjectStateManager.ChangeObjectState(employeeFromDB, System.Data.EntityState.Modified);
db.SaveChanges();
return RedirectToAction("Details", new { id = employee.Id });
}
return View(employee);
}
Edit.cshtml view
@model MVCDemo.Models.Employee
@{
ViewBag.Title = "Edit";
}
<div style="font-family:Arial">
@using (Html.BeginForm())
{
@Html.EditorForModel()
<br />
<br />
<input type="submit" value="Save" />
}
</div>
Part 40 - Using displayname, displayformat, & scaffoldcolumn attributes
Part 41 - Using datatype and displaycolumn attributes
Part 42 - Opening a page in new browser window in mvc
HiddenInput attribute is useful when you want to render a property using input type=hidden. This attribute is extremely useful, when you don't want the user to see or edit the property, but you need to post the property value to the server when the form is submitted, so the correct record can be updated. HiddenInput is present in System.Web.Mvc namespace.
ReadOnly attribute is present in System.ComponentModel namespace. As the name suggests, this attribute is used to make a property readonly. Please note that, we will still be able to change the property value on the view, but once we post the form the model binder will respect the readonly attribute and will not move the value to the property. You can also, make property of a class readonly simply, by removing the SET accessor.
Changes to Employee.cs file used in the demo. Notice that Id property is decorated with HiddenInput attribute, and EmailAddress is decorated with ReadOnly attribute.
public class EmployeeMetadata
{
// Id property is hidden and cannot be changed
[HiddenInput(DisplayValue=false)]
public int Id { get; set; }
// EmailAddress is read only
[ReadOnly(true)]
[DataType(DataType.EmailAddress)]
public string EmailAddress { get; set; }
[ScaffoldColumn(true)]
[DataType(DataType.Currency)]
public int? Salary { get; set; }
[DataType(DataType.Url)]
[UIHint("OpenInNewWindow")]
public string PersonalWebSite { get; set; }
[DisplayAttribute(Name= "Full Name")]
public string FullName { get; set; }
[DisplayFormat(DataFormatString="{0:d}")]
public DateTime? HireDate { get; set; }
[DisplayFormat(NullDisplayText="Gender not specified")]
public string Gender { get; set; }
}
Changes to HomeController.cs file
public ActionResult Edit(int id)
{
SampleDBContext db = new SampleDBContext();
Employee employee = db.Employees.Single(x => x.Id == id);
return View(employee);
}
[HttpPost]
public ActionResult Edit(Employee employee)
{
if (ModelState.IsValid)
{
SampleDBContext db = new SampleDBContext();
Employee employeeFromDB = db.Employees.Single(x => x.Id == employee.Id);
// Populate all the properties except EmailAddrees
employeeFromDB.FullName = employee.FullName;
employeeFromDB.Gender = employee.Gender;
employeeFromDB.Age = employee.Age;
employeeFromDB.HireDate = employee.HireDate;
employeeFromDB.Salary = employee.Salary;
employeeFromDB.PersonalWebSite = employee.PersonalWebSite;
db.ObjectStateManager.ChangeObjectState(employeeFromDB, System.Data.EntityState.Modified);
db.SaveChanges();
return RedirectToAction("Details", new { id = employee.Id });
}
return View(employee);
}
Edit.cshtml view
@model MVCDemo.Models.Employee
@{
ViewBag.Title = "Edit";
}
<div style="font-family:Arial">
@using (Html.BeginForm())
{
@Html.EditorForModel()
<br />
<br />
<input type="submit" value="Save" />
}
</div>
Suggested Videos
Part 41 - Using datatype and displaycolumn attributes
Part 42 - Opening a page in new browser window in mvc
Part 43 - Hiddeninput and readonly attributes
Templated helpers are introduced in mvc 2. These built in templated helpers can be broadly classified into 2 categories.
1. Display Templates
2. Editor Templates
There are 3 DISPLAY templated helpers
@Html.Display("EmployeeData") - Used with a view that is not strongly typed. For example, if you have stored data in ViewData, then we can use this templated helper using the key that was used to store data in ViewData.
@Html.DisplayFor(model => model) - Used with strongly typed views. If your model has properties that return complex objects, then this templated helper is very useful.
@Html.DisplayForModel() - Used with strongly typed views. Walks thru each property, in the model to display the object.
Along the same lines, there are 3 EDIT templated helpers
@Html.Editor("EmployeeData")
@Html.EditorFor(model => model)
@Html.EditorForModel()
To associate metadata with model class properties, we use attributes. In the previous sessions of this video series, we have discussed about using various data annotations attributes. These templated helpers use metadata associated with the model to render the user interface.
The built-in display and edit templated helpers can be very easily customised. We will discuss this in a later video session.
We will use the following Employee class that we have been working with in the previous sessions.
[MetadataType(typeof(EmployeeMetadata))]
public partial class Employee
{
}
public class EmployeeMetadata
{
[HiddenInput(DisplayValue = false)]
public int Id { get; set; }
[ReadOnly(true)]
[DataType(DataType.EmailAddress)]
public string EmailAddress { get; set; }
[ScaffoldColumn(true)]
[DataType(DataType.Currency)]
public int? Salary { get; set; }
[DataType(DataType.Url)]
[UIHint("OpenInNewWindow")]
public string PersonalWebSite { get; set; }
[DisplayAttribute(Name = "Full Name")]
public string FullName { get; set; }
[DisplayFormat(DataFormatString = "{0:d}")]
public DateTime? HireDate { get; set; }
[DisplayFormat(NullDisplayText = "Gender not specified")]
public string Gender { get; set; }
}
Copy and paste the following Details action method in HomeController. Notice that, the employee object is stored in ViewData using "EmployeeData" key.
public ActionResult Details(int id)
{
SampleDBContext db = new SampleDBContext();
Employee employee = db.Employees.Single(x => x.Id == id);
ViewData["EmployeeData"] = employee;
return View();
}
Copy and paste the following code in Details.cshtml view. Since our employee object is in ViewData, we are using @Html.Display("EmployeeData") templated helper. At the moment "Details.cshtml" view does not have a Model associated with it. So it is not a strongly typed view.
@{
ViewBag.Title = "Details";
}
<h2>Details</h2>
<fieldset>
<legend>Employee</legend>
@Html.Display("EmployeeData")
</fieldset>
At this point, if you run the application, you should be able to view Employee details, as expected.
Now, change the implementation of "Details" action method with in home controller as shown below. Notice that, instead of storing the "Employee" object in ViewData, we are passing it to the View.
public ActionResult Details(int id)
{
SampleDBContext db = new SampleDBContext();
Employee employee = db.Employees.Single(x => x.Id == id);
return View(employee);
}
Change Details.cshtml view as below. We have specified "Employee" as the model object. So, here we are working with a strongly typed view, and hence we are using @Html.DisplayFor(model => model) templated helper. Since, none of the properties of Employee class return a complex object, the ideal choice here would be, to use @Html.DisplayForModel() templated helper. In either cases, in this scenario you will get the same output.
@model MVCDemo.Models.Employee
@{
ViewBag.Title = "Details";
}
<h2>Details</h2>
<fieldset>
<legend>Employee</legend>
@Html.DisplayFor(model => model)
</fieldset>
You work with Editor templates in the same way. In HomeController, implement Edit action method as shown below.
public ActionResult Edit(int id)
{
SampleDBContext db = new SampleDBContext();
Employee employee = db.Employees.Single(x => x.Id == id);
return View(employee);
}
and in Edit.cshtml view
@model MVCDemo.Models.Employee
@{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (@Html.BeginForm())
{
@Html.EditorForModel()
}
Part 41 - Using datatype and displaycolumn attributes
Part 42 - Opening a page in new browser window in mvc
Part 43 - Hiddeninput and readonly attributes
Templated helpers are introduced in mvc 2. These built in templated helpers can be broadly classified into 2 categories.
1. Display Templates
2. Editor Templates
There are 3 DISPLAY templated helpers
@Html.Display("EmployeeData") - Used with a view that is not strongly typed. For example, if you have stored data in ViewData, then we can use this templated helper using the key that was used to store data in ViewData.
@Html.DisplayFor(model => model) - Used with strongly typed views. If your model has properties that return complex objects, then this templated helper is very useful.
@Html.DisplayForModel() - Used with strongly typed views. Walks thru each property, in the model to display the object.
Along the same lines, there are 3 EDIT templated helpers
@Html.Editor("EmployeeData")
@Html.EditorFor(model => model)
@Html.EditorForModel()
To associate metadata with model class properties, we use attributes. In the previous sessions of this video series, we have discussed about using various data annotations attributes. These templated helpers use metadata associated with the model to render the user interface.
The built-in display and edit templated helpers can be very easily customised. We will discuss this in a later video session.
We will use the following Employee class that we have been working with in the previous sessions.
[MetadataType(typeof(EmployeeMetadata))]
public partial class Employee
{
}
public class EmployeeMetadata
{
[HiddenInput(DisplayValue = false)]
public int Id { get; set; }
[ReadOnly(true)]
[DataType(DataType.EmailAddress)]
public string EmailAddress { get; set; }
[ScaffoldColumn(true)]
[DataType(DataType.Currency)]
public int? Salary { get; set; }
[DataType(DataType.Url)]
[UIHint("OpenInNewWindow")]
public string PersonalWebSite { get; set; }
[DisplayAttribute(Name = "Full Name")]
public string FullName { get; set; }
[DisplayFormat(DataFormatString = "{0:d}")]
public DateTime? HireDate { get; set; }
[DisplayFormat(NullDisplayText = "Gender not specified")]
public string Gender { get; set; }
}
Copy and paste the following Details action method in HomeController. Notice that, the employee object is stored in ViewData using "EmployeeData" key.
public ActionResult Details(int id)
{
SampleDBContext db = new SampleDBContext();
Employee employee = db.Employees.Single(x => x.Id == id);
ViewData["EmployeeData"] = employee;
return View();
}
Copy and paste the following code in Details.cshtml view. Since our employee object is in ViewData, we are using @Html.Display("EmployeeData") templated helper. At the moment "Details.cshtml" view does not have a Model associated with it. So it is not a strongly typed view.
@{
ViewBag.Title = "Details";
}
<h2>Details</h2>
<fieldset>
<legend>Employee</legend>
@Html.Display("EmployeeData")
</fieldset>
At this point, if you run the application, you should be able to view Employee details, as expected.
Now, change the implementation of "Details" action method with in home controller as shown below. Notice that, instead of storing the "Employee" object in ViewData, we are passing it to the View.
public ActionResult Details(int id)
{
SampleDBContext db = new SampleDBContext();
Employee employee = db.Employees.Single(x => x.Id == id);
return View(employee);
}
Change Details.cshtml view as below. We have specified "Employee" as the model object. So, here we are working with a strongly typed view, and hence we are using @Html.DisplayFor(model => model) templated helper. Since, none of the properties of Employee class return a complex object, the ideal choice here would be, to use @Html.DisplayForModel() templated helper. In either cases, in this scenario you will get the same output.
@model MVCDemo.Models.Employee
@{
ViewBag.Title = "Details";
}
<h2>Details</h2>
<fieldset>
<legend>Employee</legend>
@Html.DisplayFor(model => model)
</fieldset>
You work with Editor templates in the same way. In HomeController, implement Edit action method as shown below.
public ActionResult Edit(int id)
{
SampleDBContext db = new SampleDBContext();
Employee employee = db.Employees.Single(x => x.Id == id);
return View(employee);
}
and in Edit.cshtml view
@model MVCDemo.Models.Employee
@{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (@Html.BeginForm())
{
@Html.EditorForModel()
}
Suggested Videos
Part 42 - Opening a page in new browser window in mvc
Part 43 - Hiddeninput and readonly attributes
Part 44 - Display and edit templated helpers
In this video, we will discuss customizing datetime editor template. Please watch Part 44, before proceeding. We will be using the same example, that we worked with in Part 44.
At the moment, when you navigate to localhost/MVCDemo/Home/Edit/1, the output is as shown below.

Notice that, for HireDate, users have to type in the date. Dates have got different formats. For example, MM/DD/YYYY or DD/MM/YY etc. So, different users may type it differently. Also, from a user experience, it is better to display a DateTime picker from which the user can simply select the date.
The built-in DateTime editor template used by MVC, simply displays a textbox for editing Dates. So, let's customize the DateTime editor template, to use jQuery calendar. We want the output as shown below.

The following is the convention used by MVC to find the customized templates
1. The customized display templates must be in a sub-folder that is named - DisplayTemplates. Editor templates must be in a sub-folder that is named - EditorTemplates.
2. These sub-folders can live in "Shared" folder, or a specific views folder. If these folders are present in the Shared folder, then the templates are available for all the views. If they are in a specific views folder, then, they are available only for that set of views.
3. The name of the template must match the name of the type. For example, as we are customizing DateTime template, the name of the template in this case has to be DateTime.ascx or DateTime.cshtml.
Adding a Custom DateTime Editor template
Step 1: If "Shared" folder does not already exists in your project, right click on the project in solution explorer and add it.
Step 2: Right click on the "Shared" folder, and "EditorTemplates" folder.
Step 3: Right click on "EditorTemplates" folder and add a view with name = DateTime
Step 4: Copy and paste the following code in DateTime.cshtml partial view
@model DateTime?
@Html.TextBox("", (Model.HasValue ? Model.Value.ToString("dd/MM/yyyy") : string.Empty), new { @class = "date" })
Note: Please refer to the following MSDN articel for all the DateTime format strings
http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx
Step 5: Copy and paste the following code in Edit.cshtml view
@model MVCDemo.Models.Employee
@{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
<script src="~/Scripts/jquery-1.7.1.min.js" type="text/javascript"></script>
<script src="~/Scripts/jquery-ui-1.8.20.min.js" type="text/javascript"></script>
<link href="~/Content/Site.css" rel="stylesheet" type="text/css" />
<link href="~/Content/themes/base/jquery.ui.all.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">
$(function()
{
$("input:text.date").datepicker(
{
dateFormat: "dd/mm/yy"
});
});
</script>
@using (@Html.BeginForm())
{
@Html.EditorForModel()
<br />
<input type="submit" value="Save" />
}
Note: Please refer to the following jQuery link for DateTime format strings
http://jqueryui.com/resources/demos/datepicker/date-formats.html
The following jQuery scripts and css files are required for jQuery DateTime picker control. However, these files may change depending on the version of jQuery you are working with.
Scripts/jquery-1.7.1.min.js
Scripts/jquery-ui-1.8.20.min.js
Content/Site.css
Content/themes/base/jquery.ui.all.css
Part 42 - Opening a page in new browser window in mvc
Part 43 - Hiddeninput and readonly attributes
Part 44 - Display and edit templated helpers
In this video, we will discuss customizing datetime editor template. Please watch Part 44, before proceeding. We will be using the same example, that we worked with in Part 44.
At the moment, when you navigate to localhost/MVCDemo/Home/Edit/1, the output is as shown below.

Notice that, for HireDate, users have to type in the date. Dates have got different formats. For example, MM/DD/YYYY or DD/MM/YY etc. So, different users may type it differently. Also, from a user experience, it is better to display a DateTime picker from which the user can simply select the date.
The built-in DateTime editor template used by MVC, simply displays a textbox for editing Dates. So, let's customize the DateTime editor template, to use jQuery calendar. We want the output as shown below.

The following is the convention used by MVC to find the customized templates
1. The customized display templates must be in a sub-folder that is named - DisplayTemplates. Editor templates must be in a sub-folder that is named - EditorTemplates.
2. These sub-folders can live in "Shared" folder, or a specific views folder. If these folders are present in the Shared folder, then the templates are available for all the views. If they are in a specific views folder, then, they are available only for that set of views.
3. The name of the template must match the name of the type. For example, as we are customizing DateTime template, the name of the template in this case has to be DateTime.ascx or DateTime.cshtml.
Adding a Custom DateTime Editor template
Step 1: If "Shared" folder does not already exists in your project, right click on the project in solution explorer and add it.
Step 2: Right click on the "Shared" folder, and "EditorTemplates" folder.
Step 3: Right click on "EditorTemplates" folder and add a view with name = DateTime
Step 4: Copy and paste the following code in DateTime.cshtml partial view
@model DateTime?
@Html.TextBox("", (Model.HasValue ? Model.Value.ToString("dd/MM/yyyy") : string.Empty), new { @class = "date" })
Note: Please refer to the following MSDN articel for all the DateTime format strings
http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx
Step 5: Copy and paste the following code in Edit.cshtml view
@model MVCDemo.Models.Employee
@{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
<script src="~/Scripts/jquery-1.7.1.min.js" type="text/javascript"></script>
<script src="~/Scripts/jquery-ui-1.8.20.min.js" type="text/javascript"></script>
<link href="~/Content/Site.css" rel="stylesheet" type="text/css" />
<link href="~/Content/themes/base/jquery.ui.all.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">
$(function()
{
$("input:text.date").datepicker(
{
dateFormat: "dd/mm/yy"
});
});
</script>
@using (@Html.BeginForm())
{
@Html.EditorForModel()
<br />
<input type="submit" value="Save" />
}
Note: Please refer to the following jQuery link for DateTime format strings
http://jqueryui.com/resources/demos/datepicker/date-formats.html
The following jQuery scripts and css files are required for jQuery DateTime picker control. However, these files may change depending on the version of jQuery you are working with.
Scripts/jquery-1.7.1.min.js
Scripts/jquery-ui-1.8.20.min.js
Content/Site.css
Content/themes/base/jquery.ui.all.css
Part 46 - Accessing model metadata from custom templated helpers
Suggested Videos
Part 43 - Hiddeninput and readonly attributes
Part 44 - Display and edit templated helpers
Part 45 - Customize display and edit templates
In this video, we will discuss, accessing model metadata from with in customized display and edit templated helpers. We will be using the same example, that we worked with in Part 45.
In Part 45, we have customized DateTime editor template to use jQuery calendar. The problem with this template is that, we have hard-coded the date format string to dd/MM/yyyy. So, from this point, any DateTime property that uses this template will format the date using the hard-coded date format string.
We want our DateTime template to be generic. We don't want any hard-coded logic, with-in the DateTime editor template. The DisplayFormat attribute on the HireDate property of the Employee class must be used to determine the display format of the date.
Let's remove the hard-coded date format string (dd/MM/yyyy) from DateTime.cshtml.
@Html.TextBox("", Model.HasValue ? Model.Value.ToString("dd/MM/yyyy") : "", new { @class = "date" })
Decorate HireDate property in Employee class, with DisplayFormat attribute as shown below. Also, make sure ApplyFormatInEditMode parameter is set to true, otherwise the formatting will not be applied in Edit mode.
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode=true)]
public DateTime? HireDate { get; set; }
Now, change the code in DateTime.cshtml to use the formatted datetime value as show below. Notice that, we are using ViewData.TemplateInfo.FormattedModelValue.
@Html.TextBox("", Model.HasValue ? ViewData.TemplateInfo.FormattedModelValue : "", new { @class = "date" })
To access model metadata in templates, use @ViewData.ModelMetadata. For, example to access the DisplayFormatString, use @ViewData.ModelMetadata.DisplayFormatString. Along the same lines, if you want to know, the name of the containing class(i.e the class that contains the HireDate property) then use @ViewData.ModelMetadata.ContainerType.ToString().
Part 43 - Hiddeninput and readonly attributes
Part 44 - Display and edit templated helpers
Part 45 - Customize display and edit templates
In this video, we will discuss, accessing model metadata from with in customized display and edit templated helpers. We will be using the same example, that we worked with in Part 45.
In Part 45, we have customized DateTime editor template to use jQuery calendar. The problem with this template is that, we have hard-coded the date format string to dd/MM/yyyy. So, from this point, any DateTime property that uses this template will format the date using the hard-coded date format string.
We want our DateTime template to be generic. We don't want any hard-coded logic, with-in the DateTime editor template. The DisplayFormat attribute on the HireDate property of the Employee class must be used to determine the display format of the date.
Let's remove the hard-coded date format string (dd/MM/yyyy) from DateTime.cshtml.
@Html.TextBox("", Model.HasValue ? Model.Value.ToString("dd/MM/yyyy") : "", new { @class = "date" })
Decorate HireDate property in Employee class, with DisplayFormat attribute as shown below. Also, make sure ApplyFormatInEditMode parameter is set to true, otherwise the formatting will not be applied in Edit mode.
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode=true)]
public DateTime? HireDate { get; set; }
Now, change the code in DateTime.cshtml to use the formatted datetime value as show below. Notice that, we are using ViewData.TemplateInfo.FormattedModelValue.
@Html.TextBox("", Model.HasValue ? ViewData.TemplateInfo.FormattedModelValue : "", new { @class = "date" })
To access model metadata in templates, use @ViewData.ModelMetadata. For, example to access the DisplayFormatString, use @ViewData.ModelMetadata.DisplayFormatString. Along the same lines, if you want to know, the name of the containing class(i.e the class that contains the HireDate property) then use @ViewData.ModelMetadata.ContainerType.ToString().
Suggested Videos
Part 44 - Display and edit templated helpers
Part 45 - Customize display and edit templates
Part 46 - Accessing model metada from custom templated helpers
In this video, we will discuss displaying images in MVC application. In Part 48, we will create a custom html helper to display images. We will be using the example, that we worked with in Part 46. We want to display Employee photo, along with the personal details as you can see in the image below.

Alter table tblEmployee to add Photo, and AlternateText columns.
Alter table tblEmployee Add Photo nvarchar(100), AlternateText nvarchar(100)
Update Photo and AlternateText columns
Update tblEmployee set Photo='~/Photos/JohnSmith.png',
AlternateText = 'John Smith Photo' where Id = 1
Right click on the solution explorer and add "Photos" folder. Download the following image and paste in "Photos" folder.

Now, in MVCDemo project, update SampleDataModel.edmx.
1. Right click on "Employee" table and select "Update Model from database" option
2. On "Update Wizard" window, click on "Refresh" tab
3. Expand tables node, and select "tblEmployee" table
4. Finally click "Finish"
At this point, "Photo" and "AlternateText" properties must be added to the auto-generated "Employee" class.
Generate Details view
1. Delete "Details.cshtml" view, if it already exists.
2. Right click on "Details" action method and select "Add View"
3. In "Add View" window, set
View Name = Details
View engine = Razor
Create a strongly typed view = Select the checkbox
Model class = Employee(MVCDemo.Models)
Scaffold template = Details
Notice that for Photo and AlternateText properties, the following HTML is generated. At this point, if you run the application, instead of rendering the photo, the PhotoPath and AlternateText property values are displayed.
<div class="display-label">
@Html.DisplayNameFor(model => model.Photo)
</div>
<div class="display-field">
@Html.DisplayFor(model => model.Photo)
</div>
<div class="display-label">
@Html.DisplayNameFor(model => model.AlternateText)
</div>
<div class="display-field">
@Html.DisplayFor(model => model.AlternateText)
</div>
Replace the above code with the following. Notice that, we are using Url.Content() html helper method. This method resolves a url for a resource when we pass it the relative path.
<div class="display-label">
@Html.DisplayNameFor(model => model.Photo)
</div>
<div class="display-field">
<img src="@Url.Content(@Model.Photo)" alt="@Model.AlternateText" />
</div>
Run the application, and notice that, the image is rendered as expected. In our next video, we will discuss creating a custom html image helper.
Part 44 - Display and edit templated helpers
Part 45 - Customize display and edit templates
Part 46 - Accessing model metada from custom templated helpers
In this video, we will discuss displaying images in MVC application. In Part 48, we will create a custom html helper to display images. We will be using the example, that we worked with in Part 46. We want to display Employee photo, along with the personal details as you can see in the image below.

Alter table tblEmployee to add Photo, and AlternateText columns.
Alter table tblEmployee Add Photo nvarchar(100), AlternateText nvarchar(100)
Update Photo and AlternateText columns
Update tblEmployee set Photo='~/Photos/JohnSmith.png',
AlternateText = 'John Smith Photo' where Id = 1
Right click on the solution explorer and add "Photos" folder. Download the following image and paste in "Photos" folder.

Now, in MVCDemo project, update SampleDataModel.edmx.
1. Right click on "Employee" table and select "Update Model from database" option
2. On "Update Wizard" window, click on "Refresh" tab
3. Expand tables node, and select "tblEmployee" table
4. Finally click "Finish"
At this point, "Photo" and "AlternateText" properties must be added to the auto-generated "Employee" class.
Generate Details view
1. Delete "Details.cshtml" view, if it already exists.
2. Right click on "Details" action method and select "Add View"
3. In "Add View" window, set
View Name = Details
View engine = Razor
Create a strongly typed view = Select the checkbox
Model class = Employee(MVCDemo.Models)
Scaffold template = Details
Notice that for Photo and AlternateText properties, the following HTML is generated. At this point, if you run the application, instead of rendering the photo, the PhotoPath and AlternateText property values are displayed.
<div class="display-label">
@Html.DisplayNameFor(model => model.Photo)
</div>
<div class="display-field">
@Html.DisplayFor(model => model.Photo)
</div>
<div class="display-label">
@Html.DisplayNameFor(model => model.AlternateText)
</div>
<div class="display-field">
@Html.DisplayFor(model => model.AlternateText)
</div>
Replace the above code with the following. Notice that, we are using Url.Content() html helper method. This method resolves a url for a resource when we pass it the relative path.
<div class="display-label">
@Html.DisplayNameFor(model => model.Photo)
</div>
<div class="display-field">
<img src="@Url.Content(@Model.Photo)" alt="@Model.AlternateText" />
</div>
Run the application, and notice that, the image is rendered as expected. In our next video, we will discuss creating a custom html image helper.
Part 48 - Custom html helpers in mvc
Suggested Videos
Part 45 - Customize display and edit templates
Part 46 - Accessing model metada from custom templated helpers
Part 47 - Displaying images in MVC
In this video, we will discuss, creating custom html helpers. We will be using the example, that we worked with in Part 47. Please watch Part 47, before proceeding.
In Part 47, to render the image, we used the following code. We are building the image tag, by passing values for "src" and "alt" attributes.
<img src="@Url.Content(@Model.Photo)" alt="@Model.AlternateText" />
Though the above code is not very complex, it still makes sense to move this logic into it's own helper method. We don't want any complicated logic in our views. Views should be as simple as possible. Don't you think, it would be very nice, if we can render the image, using Image() html helper method as shown below. Unfortunately, MVC does not have built-in Image() html helper. So, let's build our own custom image html helper method.
@Html.Image(Model.Photo, Model.AlternateText)
Let's take a step back and understand html heper methods. The HTML helper method simply returns a string. To generate a textbox, we use the following code in our view.
@Html.TextBox("TextBox Name")
So, here TextBox() is an extension method defined in HtmlHelper class. In the above code, Html is the property of the View, which returns an instance of the HtmlHelper class.
Let's now add, Image() extension method, to HtmlHelper class.
1. Right click on MVCDemo project and add "CustomHtmlHelpers" folder.
2. Right click on "CustomHtmlHelpers" folder and add "CustomHtmlHelpers.cs" class file.
3. Copy and paste the following code. The code is commented and self-explanatory. TagBuilder class is in System.Web.Mvc namespace.
namespace MVCDemo.CustomHtmlHelpers
{
public static class CustomHtmlHelpers
{
public static IHtmlString Image(this HtmlHelper helper, string src, string alt)
{
// Build <img> tag
TagBuilder tb = new TagBuilder("img");
// Add "src" attribute
tb.Attributes.Add("src", VirtualPathUtility.ToAbsolute(src));
// Add "alt" attribute
tb.Attributes.Add("alt", alt);
// return MvcHtmlString. This class implements IHtmlString
// interface. IHtmlStrings will not be html encoded.
return new MvcHtmlString(tb.ToString(TagRenderMode.SelfClosing));
}
}
}
To use the custom Image() html helper in Details.cshtml view, please include the folowing using statement in Details.cshtml
@using MVCDemo.CustomHtmlHelpers;
As we intend to use this Image() html helper, in all our views, let's include "MVCDemo.CustomHtmlHelpers" namespace in web.config. This eliminates the need to include the namespace, in every view.
<system.web.webPages.razor>
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="MVCDemo.CustomHtmlHelpers" />
</namespaces>
</pages>
<host ....../>
</system.web.webPages.razor>
If you intend to use the Image() custom html helper, only with a set of views, then, include a web.config file in the specific views folder, and then specify the namespace in it.
Part 45 - Customize display and edit templates
Part 46 - Accessing model metada from custom templated helpers
Part 47 - Displaying images in MVC
In this video, we will discuss, creating custom html helpers. We will be using the example, that we worked with in Part 47. Please watch Part 47, before proceeding.
In Part 47, to render the image, we used the following code. We are building the image tag, by passing values for "src" and "alt" attributes.
<img src="@Url.Content(@Model.Photo)" alt="@Model.AlternateText" />
Though the above code is not very complex, it still makes sense to move this logic into it's own helper method. We don't want any complicated logic in our views. Views should be as simple as possible. Don't you think, it would be very nice, if we can render the image, using Image() html helper method as shown below. Unfortunately, MVC does not have built-in Image() html helper. So, let's build our own custom image html helper method.
@Html.Image(Model.Photo, Model.AlternateText)
Let's take a step back and understand html heper methods. The HTML helper method simply returns a string. To generate a textbox, we use the following code in our view.
@Html.TextBox("TextBox Name")
So, here TextBox() is an extension method defined in HtmlHelper class. In the above code, Html is the property of the View, which returns an instance of the HtmlHelper class.
Let's now add, Image() extension method, to HtmlHelper class.
1. Right click on MVCDemo project and add "CustomHtmlHelpers" folder.
2. Right click on "CustomHtmlHelpers" folder and add "CustomHtmlHelpers.cs" class file.
3. Copy and paste the following code. The code is commented and self-explanatory. TagBuilder class is in System.Web.Mvc namespace.
namespace MVCDemo.CustomHtmlHelpers
{
public static class CustomHtmlHelpers
{
public static IHtmlString Image(this HtmlHelper helper, string src, string alt)
{
// Build <img> tag
TagBuilder tb = new TagBuilder("img");
// Add "src" attribute
tb.Attributes.Add("src", VirtualPathUtility.ToAbsolute(src));
// Add "alt" attribute
tb.Attributes.Add("alt", alt);
// return MvcHtmlString. This class implements IHtmlString
// interface. IHtmlStrings will not be html encoded.
return new MvcHtmlString(tb.ToString(TagRenderMode.SelfClosing));
}
}
}
To use the custom Image() html helper in Details.cshtml view, please include the folowing using statement in Details.cshtml
@using MVCDemo.CustomHtmlHelpers;
As we intend to use this Image() html helper, in all our views, let's include "MVCDemo.CustomHtmlHelpers" namespace in web.config. This eliminates the need to include the namespace, in every view.
<system.web.webPages.razor>
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="MVCDemo.CustomHtmlHelpers" />
</namespaces>
</pages>
<host ....../>
</system.web.webPages.razor>
If you intend to use the Image() custom html helper, only with a set of views, then, include a web.config file in the specific views folder, and then specify the namespace in it.
Suggested Videos
Part 46 - Accessing model metada from custom templated helpers
Part 47 - Displaying images in MVC
Part 48 - Custom html helpers in mvc
In this video, we will discuss
1. What is HTML encoding
2. Why would you html encode
3. How to avoid html encoding in aspx and razor views
What is HTML encoding?
HTML encoding is the process of replacing ASCII characters with their 'HTML Entity' equivalents. For example replacing

Why would you html encode?
To avoid cross site scripting attacks, all output is automatically html encoded in mvc. We will discuss cross-site scripting attack in a later video session.
Avoiding html encoding in razor views:
Sometimes, we have to avoid HTML encoding. There are 2 ways to disable html encoding
1. @Html.Raw("YourHTMLString")
2. Strings of type IHtmlString are not encoded
Consider the following custom Image() html helper.
public static class CustomHtmlHelpers
{
public static IHtmlString Image(this HtmlHelper helper, string src, string alt)
{
TagBuilder tb = new TagBuilder("img");
tb.Attributes.Add("src", VirtualPathUtility.ToAbsolute(src));
tb.Attributes.Add("alt", alt);
return new MvcHtmlString(tb.ToString(TagRenderMode.SelfClosing));
}
}
Notice that, this custom Image() HTML helper method returns string of type, IHtmlString. Strings of type IHtmlString are excluded from html encoding. So, when we invoke Image() helper method from a razor view as shown below, the image is rendered as expected.
@Html.Image(@Model.Photo, @Model.AlternateText)
However, if you modify the Image() method to return string of type System.String, the HTML is encoded and that's what is shown on the view, instead of actually rendering the image.
<img alt="John Smith Photo" src="/MVCDemo/Photos/JohnSmith.png" />
@Html.Raw() method can also be used to avoid automatic html encoding. Notice that, the string that is returned by Image() method is passed as the input for Raw() method, which renders the image as expected.
@Html.Raw(Html.Image(@Model.Photo, @Model.AlternateText))
Avoiding html encoding in ASPX views:
<%: %> syntax will automatically encode html in aspx views. So, the following will encode and display the html, instead of rendering the image. At the moment, the custom Image() html helper method is returning string of type system.string. If you make this method return IHtmlString, then the following code will render the image instead of html encoding it.
<%: Html.Image(Model.Photo, Model.AlternateText) %>
To avoid automatic html encoding, you can use
1. <%= %>
2. Html.Raw()
3. Strings of type IHtmlString are not encoded
Both the following code blocks will render the image
<%= Html.Image(Model.Photo, Model.AlternateText) %>
OR
<%: Html.Raw(Html.Image(Model.Photo, Model.AlternateText)) %>
Different techniques to avoid automatic html encoding in MVC

Part 46 - Accessing model metada from custom templated helpers
Part 47 - Displaying images in MVC
Part 48 - Custom html helpers in mvc
In this video, we will discuss
1. What is HTML encoding
2. Why would you html encode
3. How to avoid html encoding in aspx and razor views
What is HTML encoding?
HTML encoding is the process of replacing ASCII characters with their 'HTML Entity' equivalents. For example replacing

Why would you html encode?
To avoid cross site scripting attacks, all output is automatically html encoded in mvc. We will discuss cross-site scripting attack in a later video session.
Avoiding html encoding in razor views:
Sometimes, we have to avoid HTML encoding. There are 2 ways to disable html encoding
1. @Html.Raw("YourHTMLString")
2. Strings of type IHtmlString are not encoded
Consider the following custom Image() html helper.
public static class CustomHtmlHelpers
{
public static IHtmlString Image(this HtmlHelper helper, string src, string alt)
{
TagBuilder tb = new TagBuilder("img");
tb.Attributes.Add("src", VirtualPathUtility.ToAbsolute(src));
tb.Attributes.Add("alt", alt);
return new MvcHtmlString(tb.ToString(TagRenderMode.SelfClosing));
}
}
Notice that, this custom Image() HTML helper method returns string of type, IHtmlString. Strings of type IHtmlString are excluded from html encoding. So, when we invoke Image() helper method from a razor view as shown below, the image is rendered as expected.
@Html.Image(@Model.Photo, @Model.AlternateText)
However, if you modify the Image() method to return string of type System.String, the HTML is encoded and that's what is shown on the view, instead of actually rendering the image.
<img alt="John Smith Photo" src="/MVCDemo/Photos/JohnSmith.png" />
@Html.Raw() method can also be used to avoid automatic html encoding. Notice that, the string that is returned by Image() method is passed as the input for Raw() method, which renders the image as expected.
@Html.Raw(Html.Image(@Model.Photo, @Model.AlternateText))
Avoiding html encoding in ASPX views:
<%: %> syntax will automatically encode html in aspx views. So, the following will encode and display the html, instead of rendering the image. At the moment, the custom Image() html helper method is returning string of type system.string. If you make this method return IHtmlString, then the following code will render the image instead of html encoding it.
<%: Html.Image(Model.Photo, Model.AlternateText) %>
To avoid automatic html encoding, you can use
1. <%= %>
2. Html.Raw()
3. Strings of type IHtmlString are not encoded
Both the following code blocks will render the image
<%= Html.Image(Model.Photo, Model.AlternateText) %>
OR
<%: Html.Raw(Html.Image(Model.Photo, Model.AlternateText)) %>
Different techniques to avoid automatic html encoding in MVC

Part 50 - Detect errors in views at compile time
Suggested Videos
Part 47 - Displaying images in MVC
Part 48 - Custom html helpers in mvc
Part 49 - Html encoding in asp.net mvc
In this video, we will discuss, detecting errors in views at compile-time rather than at run-time.
The following code will display employee's FullName and Gender. Here we are working with a strongly typed view. Employee is the model class for this view. This class has got "FullName" and "Gender" properties.
@model MVCDemo.Models.Employee
<fieldset>
<legend>Employee</legend>
<div class="display-label">
@Html.DisplayNameFor(model => model.FullName)
</div>
<div class="display-field">
@Html.DisplayFor(model => model.FullName)
</div>
<div class="display-label">
@Html.DisplayNameFor(model => model.Gender)
</div>
<div class="display-field">
@Html.DisplayFor(model => model.Gender)
</div>
</fieldset>
For example, if you mis-spell FullName property as shown below, and when you compile the project, you wouldn't get any compile time errors.
@Html.DisplayNameFor(model => model.FullName1)
You will only come to know, about the error when the page crashes at run-time. If you want to enable compile time error checking for views in MVC
1. Open MVC project file using a notepad. Project files have the extension of .csproj or .vbproj
2. Search for MvcBuildViews under PropertyGroup. MvcBuildViews is false by default. Turn this to true as shown below.
<MvcBuildViews>true</MvcBuildViews>
3. Save the changes.
If you now build the project, you should get compile time error.
Please Note: Pre-compiling views is different from compile-time error checking. We will discuss pre-compiling views in a later video session.
Part 47 - Displaying images in MVC
Part 48 - Custom html helpers in mvc
Part 49 - Html encoding in asp.net mvc
In this video, we will discuss, detecting errors in views at compile-time rather than at run-time.
The following code will display employee's FullName and Gender. Here we are working with a strongly typed view. Employee is the model class for this view. This class has got "FullName" and "Gender" properties.
@model MVCDemo.Models.Employee
<fieldset>
<legend>Employee</legend>
<div class="display-label">
@Html.DisplayNameFor(model => model.FullName)
</div>
<div class="display-field">
@Html.DisplayFor(model => model.FullName)
</div>
<div class="display-label">
@Html.DisplayNameFor(model => model.Gender)
</div>
<div class="display-field">
@Html.DisplayFor(model => model.Gender)
</div>
</fieldset>
For example, if you mis-spell FullName property as shown below, and when you compile the project, you wouldn't get any compile time errors.
@Html.DisplayNameFor(model => model.FullName1)
You will only come to know, about the error when the page crashes at run-time. If you want to enable compile time error checking for views in MVC
1. Open MVC project file using a notepad. Project files have the extension of .csproj or .vbproj
2. Search for MvcBuildViews under PropertyGroup. MvcBuildViews is false by default. Turn this to true as shown below.
<MvcBuildViews>true</MvcBuildViews>
3. Save the changes.
If you now build the project, you should get compile time error.
Please Note: Pre-compiling views is different from compile-time error checking. We will discuss pre-compiling views in a later video session.
Suggested Videos
Part 48 - Custom html helpers in mvc
Part 49 - Html encoding in asp.net mvc
Part 50 - Detect errors in views at compile time
There are several ways available to pass data from a controller to a view in an mvc application.
1. ViewBag or ViewData
2. Dynamic type
3. Strongly typed view
The following are the advantages of using strongly typed views. We get
1. Intellisense and
2. Compile-time error checking
With ViewBag and Dynamic type, we don't have these advantages.
Using ViewBag:
Notice that, the employee object is stored in ViewBag.
In HomeController.cs
public ActionResult Details(int id)
{
SampleDBContext db = new SampleDBContext();
Employee employee = db.Employees.Single(x => x.Id == id);
ViewBag.EmployeeData = employee;
return View();
}
We want to display employee FullName and Gender. Notice that, as we are typing FullName and Gender properties, we don't get intellisense. Also, if we mis-spell FullName or Gender properties, we will not get any compilation errors. We will come to know about these errors only at runtime.
In Details.cshtml View
<div class="display-label">
@Html.DisplayName("FullName")
</div>
<div class="display-field">
@ViewBag.EmployeeData.FullName
</div>
<div class="display-label">
@Html.DisplayName("Gender")
</div>
<div class="display-field">
@ViewBag.EmployeeData.Gender
</div>
Using Dynamic Type:
In HomeController.cs
public ActionResult Details(int id)
{
SampleDBContext db = new SampleDBContext();
Employee employee = db.Employees.Single(x => x.Id == id);
return View(employee);
}
In Details.cshtml View
@model dynamic
<div class="display-label">
@Html.DisplayName("FullName")
</div>
<div class="display-field">
@Model.FullName
</div>
<div class="display-label">
@Html.DisplayName("Gender")
</div>
<div class="display-field">
@Model.Gender
</div>
With dynamic type also, we don't get intellisense and compile-time error checking.
Using Strongly Typed View: No change is required in the controller action method. Make the following change to Details.cshtml view. Notice that the view is strongly typed against Employee model class. We get intellisense and if we mis-spell a property name, we get to know about it at compile time.
@model MVCDemo.Models.Employee
<div class="display-label">
@Html.DisplayName("FullName")
</div>
<div class="display-field">
@Model.FullName
</div>
<div class="display-label">
@Html.DisplayName("Gender")
</div>
<div class="display-field">
@Model.Gender
</div>
Please Note: We discussed enabling compile time error checking in views in Part 50 of the MVC tutorial.
Part 48 - Custom html helpers in mvc
Part 49 - Html encoding in asp.net mvc
Part 50 - Detect errors in views at compile time
There are several ways available to pass data from a controller to a view in an mvc application.
1. ViewBag or ViewData
2. Dynamic type
3. Strongly typed view
The following are the advantages of using strongly typed views. We get
1. Intellisense and
2. Compile-time error checking
With ViewBag and Dynamic type, we don't have these advantages.
Using ViewBag:
Notice that, the employee object is stored in ViewBag.
In HomeController.cs
public ActionResult Details(int id)
{
SampleDBContext db = new SampleDBContext();
Employee employee = db.Employees.Single(x => x.Id == id);
ViewBag.EmployeeData = employee;
return View();
}
We want to display employee FullName and Gender. Notice that, as we are typing FullName and Gender properties, we don't get intellisense. Also, if we mis-spell FullName or Gender properties, we will not get any compilation errors. We will come to know about these errors only at runtime.
In Details.cshtml View
<div class="display-label">
@Html.DisplayName("FullName")
</div>
<div class="display-field">
@ViewBag.EmployeeData.FullName
</div>
<div class="display-label">
@Html.DisplayName("Gender")
</div>
<div class="display-field">
@ViewBag.EmployeeData.Gender
</div>
Using Dynamic Type:
In HomeController.cs
public ActionResult Details(int id)
{
SampleDBContext db = new SampleDBContext();
Employee employee = db.Employees.Single(x => x.Id == id);
return View(employee);
}
In Details.cshtml View
@model dynamic
<div class="display-label">
@Html.DisplayName("FullName")
</div>
<div class="display-field">
@Model.FullName
</div>
<div class="display-label">
@Html.DisplayName("Gender")
</div>
<div class="display-field">
@Model.Gender
</div>
With dynamic type also, we don't get intellisense and compile-time error checking.
Using Strongly Typed View: No change is required in the controller action method. Make the following change to Details.cshtml view. Notice that the view is strongly typed against Employee model class. We get intellisense and if we mis-spell a property name, we get to know about it at compile time.
@model MVCDemo.Models.Employee
<div class="display-label">
@Html.DisplayName("FullName")
</div>
<div class="display-field">
@Model.FullName
</div>
<div class="display-label">
@Html.DisplayName("Gender")
</div>
<div class="display-field">
@Model.Gender
</div>
Please Note: We discussed enabling compile time error checking in views in Part 50 of the MVC tutorial.
Part 52 - Partial views in mvc
Suggested Videos
Part 49 - Html encoding in asp.net mvc
Part 50 - Detect errors in views at compile time
Part 51 - Advantages of using strongly typed views
In this video we will discuss partial views in mvc.
If you are an asp.net web-forms developer, then you will realize that partial views in mvc are similar to user controls in asp.net webforms.
Partial views are used to encapsulate re-usable view logic and are a great means to simplify the complexity of views. These partial views can then be used on multiple views, where we need similar view logic.
If you are using web forms view engine, then the partial views have the extension of .ascx. If the view engine is razor and programming language is c#, then partial views have the extension of .cshtml. On the other hand if the programming language is visual basic, then the extension is .vbhtml.

Let us understand partial views with an example. We want to display, employee photo and his details as shown in the image below.

Index Action() method in HomeController retrurns the list of employees.
public ActionResult Index()
{
SampleDBContext db = new SampleDBContext();
return View(db.Employees.ToList());
}
We will have the following code in Index.cshtml. This view is a bit messy and complex to understand.
@model IEnumerable<MVCDemo.Models.Employee>
@foreach (var item in Model)
{
<table style="font-family:Arial; border:1px solid black; width: 300px">
<tr>
<td>
<img src="@Url.Content(item.Photo)" alt="@item.AlternateText" />
</td>
<td>
<table>
<tr>
<td><b>Age:</b></td>
<td>@item.Age</td>
</tr>
<tr>
<td><b>Gender:</b></td>
<td>@item.Gender</td>
</tr>
<tr>
<td><b>Salary:</b></td>
<td>@item.Salary</td>
</tr>
</table>
</td>
</tr>
</table>
}
To simplify this view, let's encapsulate the HTML and code that produces the employee table in a partial view.
Right click on the "Shared" folder and add a view. Set
View name = _Employee
View engine = Razor
Create a strongly typed view = Checked
Model class = Employee (MVCDemo.Models)
Scaffold template = Empty
Create as a partial view = Checked
This should add "_Employee.cshtml" partial view to the "Shared" folder.
Please note that, partial views can be added to "Shared" folder or to a specific views folder. Partial views that are in the "Shared" folder are available for all the views in the entire project, where as partial views in a specific folder are available only for the views with-in that folder.
Copy and paste the following code in "_Employee.cshtml" partial view
@model MVCDemo.Models.Employee
<table style="font-family:Arial; border:1px solid black; width: 300px">
<tr>
<td>
<img src="@Url.Content(Model.Photo)" alt="@Model.AlternateText" />
</td>
<td>
<table>
<tr>
<td><b>Age:</b></td>
<td>@Model.Age</td>
</tr>
<tr>
<td><b>Gender:</b></td>
<td>@Model.Gender</td>
</tr>
<tr>
<td><b>Salary:</b></td>
<td>@Model.Salary</td>
</tr>
</table>
</td>
</tr>
</table>
Now, make the following changes to Index.cshtml view. Notice that the view is much simplified now. To render the partial view, we are using Partial() html helper method. There are several overloaded versions of this method. We are using a version that expects 2 parameters, i.e the name of the partial view and the model object.
@model IEnumerable<MVCDemo.Models.Employee>
@foreach (var item in Model)
{
@Html.Partial("_Employee", item)
}
Part 49 - Html encoding in asp.net mvc
Part 50 - Detect errors in views at compile time
Part 51 - Advantages of using strongly typed views
In this video we will discuss partial views in mvc.
If you are an asp.net web-forms developer, then you will realize that partial views in mvc are similar to user controls in asp.net webforms.
Partial views are used to encapsulate re-usable view logic and are a great means to simplify the complexity of views. These partial views can then be used on multiple views, where we need similar view logic.
If you are using web forms view engine, then the partial views have the extension of .ascx. If the view engine is razor and programming language is c#, then partial views have the extension of .cshtml. On the other hand if the programming language is visual basic, then the extension is .vbhtml.

Let us understand partial views with an example. We want to display, employee photo and his details as shown in the image below.

Index Action() method in HomeController retrurns the list of employees.
public ActionResult Index()
{
SampleDBContext db = new SampleDBContext();
return View(db.Employees.ToList());
}
We will have the following code in Index.cshtml. This view is a bit messy and complex to understand.
@model IEnumerable<MVCDemo.Models.Employee>
@foreach (var item in Model)
{
<table style="font-family:Arial; border:1px solid black; width: 300px">
<tr>
<td>
<img src="@Url.Content(item.Photo)" alt="@item.AlternateText" />
</td>
<td>
<table>
<tr>
<td><b>Age:</b></td>
<td>@item.Age</td>
</tr>
<tr>
<td><b>Gender:</b></td>
<td>@item.Gender</td>
</tr>
<tr>
<td><b>Salary:</b></td>
<td>@item.Salary</td>
</tr>
</table>
</td>
</tr>
</table>
}
To simplify this view, let's encapsulate the HTML and code that produces the employee table in a partial view.
Right click on the "Shared" folder and add a view. Set
View name = _Employee
View engine = Razor
Create a strongly typed view = Checked
Model class = Employee (MVCDemo.Models)
Scaffold template = Empty
Create as a partial view = Checked
This should add "_Employee.cshtml" partial view to the "Shared" folder.
Please note that, partial views can be added to "Shared" folder or to a specific views folder. Partial views that are in the "Shared" folder are available for all the views in the entire project, where as partial views in a specific folder are available only for the views with-in that folder.
Copy and paste the following code in "_Employee.cshtml" partial view
@model MVCDemo.Models.Employee
<table style="font-family:Arial; border:1px solid black; width: 300px">
<tr>
<td>
<img src="@Url.Content(Model.Photo)" alt="@Model.AlternateText" />
</td>
<td>
<table>
<tr>
<td><b>Age:</b></td>
<td>@Model.Age</td>
</tr>
<tr>
<td><b>Gender:</b></td>
<td>@Model.Gender</td>
</tr>
<tr>
<td><b>Salary:</b></td>
<td>@Model.Salary</td>
</tr>
</table>
</td>
</tr>
</table>
Now, make the following changes to Index.cshtml view. Notice that the view is much simplified now. To render the partial view, we are using Partial() html helper method. There are several overloaded versions of this method. We are using a version that expects 2 parameters, i.e the name of the partial view and the model object.
@model IEnumerable<MVCDemo.Models.Employee>
@foreach (var item in Model)
{
@Html.Partial("_Employee", item)
}
Suggested Videos
Part 50 - Detect errors in views at compile time
Part 51 - Advantages of using strongly typed views
Part 52 - Partial views in mvc
In this video, we will discuss the difference between Partial() and RenderPartial() html helper methods. Both of these helper methods are used for rendering partial views.
Differences:
1. The return type of "RenderPartial" is void, where as "Partial" returns "MvcHtmlString"
2. Syntax for invoking Partial() and RenderPartial() methods in Razor views
@Html.Partial("PartialViewName")
{ Html.RenderPartial("PartialViewName"); }
3. Syntax for invoking Partial() and RenderPartial() methods in webform views
<%: Html.Partial("PartialViewName") %>
<% Html.RenderPartial("PartialViewName"); %>
The following are the 2 common interview questions related to Partial() and RenderPartial()
When would you use Partial() over RenderPartial() and vice versa?
The main difference is that "RenderPartial()" returns void and the output will be written directly to the output stream, where as the "Partial()" method returns MvcHtmlString, which can be assigned to a variable and manipulate it if required. So, when there is a need to assign the output to a variable for manipulating it, then use Partial(), else use RenderPartial().
Which one is better for performance?
From a performance perspective, rendering directly to the output stream is better. RenderPartial() does exactly the same thing and is better for performance over Partial().
Part 50 - Detect errors in views at compile time
Part 51 - Advantages of using strongly typed views
Part 52 - Partial views in mvc
In this video, we will discuss the difference between Partial() and RenderPartial() html helper methods. Both of these helper methods are used for rendering partial views.
Differences:
1. The return type of "RenderPartial" is void, where as "Partial" returns "MvcHtmlString"
2. Syntax for invoking Partial() and RenderPartial() methods in Razor views
@Html.Partial("PartialViewName")
{ Html.RenderPartial("PartialViewName"); }
3. Syntax for invoking Partial() and RenderPartial() methods in webform views
<%: Html.Partial("PartialViewName") %>
<% Html.RenderPartial("PartialViewName"); %>
The following are the 2 common interview questions related to Partial() and RenderPartial()
When would you use Partial() over RenderPartial() and vice versa?
The main difference is that "RenderPartial()" returns void and the output will be written directly to the output stream, where as the "Partial()" method returns MvcHtmlString, which can be assigned to a variable and manipulate it if required. So, when there is a need to assign the output to a variable for manipulating it, then use Partial(), else use RenderPartial().
Which one is better for performance?
From a performance perspective, rendering directly to the output stream is better. RenderPartial() does exactly the same thing and is better for performance over Partial().
Part 54 - T4 templates in asp.net mvc
Suggested
Videos Part 51 - Advantages of using strongly typed views
Part 52 - Partial views in mvc
Part 53 - Difference between html.partial and html.renderpartial
In this video, we will discuss
1. What are T4 templates and their purpose
2. Customizing T4 templates
What are T4 templates and their purpose?
T4 stands for Text Template Transformation Toolkit and are used by visual studio to generate code when you add a view or a controller.
Where does these T4 templates live?
C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ItemTemplates\[CSharp | FSharp | VisualBasic]\Web\[MVC 2 | MVC 3 | MVC 4]\CodeTemplates
What is the file extension for T4 templates?
.tt
Is it possible to customize T4 templates?
Yes, T4 templates can be customized in place, if you want the customized T4 templates available for all MVC projects on that machine.
If you want to customize T4 templates, only for a specific project, then copy "CodeTemplates" folder and paste it in the root directory of your MVC project. Right click on the template files(with .tt extension), and select Properties and delete "TextTemplatingFileGenerator".

By deleting this from CustomTool property, we are telling visual studio not to run them during the build. They will be manually called when we add a view or a controller using "Add View" and "Add Controller" dialog box.
Is it possible to add your own T4 template to the existing list of templates?
Absolutely, simply create a file with ".tt" file extension in "AddController" folder in "CodeTemplates". If it is for adding a view, then put it in "AspxCSharp"(if view engine is aspx) or "CSHTML"(if view engine is razor) folder.
No comments:
Post a Comment