In Focus

How Razor Engine Works With Views in MVC 4

This article explains with examples how the Razor Engine works with Views in MVC 4.

All of us know what views are and what their purpose are in ASP.NET MVC 4. Views in an analogy are similar to web forms in ASP.NET that are used for displaying the data or the HTML content on the user's screen.

The User interacts with our application using views. In MVC 4, views can be rendered using the following two view engines:

  • Razor View Engine: That was introduced in MVC 3 and enhanced in MVC 4.
  • Aspx view engine/WebForms View Engine: That basically supports aspx expressions and earlier versions of MVC like MVC 2.

For our demo since we are using MVC 4, the view engine that we are using is Razor.

So let's start with an example. I'm creating a new VS2010 MVC 4 project named ViewsInDepth. Select the Project Template as “Basic”. I'm not doing any unit testing here so I'm not selecting the unit testing checkbox. Once the project/solution is ready, add a new controller with the name “Home” and select the scaffolding option as Empty.

Add a new Model class with the name “Employee”. Here is the code snippet for it.

  1. namespace ViewsInDepth.Models  
  2. {  
  3.     public class Employee  
  4.     {  
  5.         public int EID { getset; }  
  6.   
  7.         public string EName { getset; }  
  8.   
  9.         public string EAdd { getset; }  
  10.   
  11.         public string EDesignation { getset; }  
  12.     }  
  13. }  
Now try to add the following code inside the Home Controller.
  1. public class HomeController : Controller  
  2.     {  
  3.         List<Employee> lstEmployees = new List<Employee>()  
  4.         {  
  5.             new Employee(){EID=1,EName="Vishal Gilbile",EAdd="Andheri",EDesignation="Sr.Software Developer"},  
  6.             new Employee(){EID=2,EName="Rahul Bandekar",EAdd="Santacruz",EDesignation="Accountant"},  
  7.             new Employee(){EID=3,EName="Neetu Agarwal", EAdd="Dadar",EDesignation="Tech Lead"},  
  8.             new Employee(){EID=4,EName="Lincy Pullan",EAdd="Worli",EDesignation="DBA"},  
  9.             new Employee(){EID=5,EName="Suvarna Bhosle",EAdd="Andheri",EDesignation="Accountant"},  
  10.             new Employee(){EID=6,EName="Paresh Rahate",EAdd="Thane",EDesignation="Project Manager"},  
  11.             new Employee(){EID=7,EName="Ollin D'Souza",EAdd="Mumbra",EDesignation="Software Developer"}  
  12.         };  
  13.   
  14.   
  15.         public ActionResult Index()  
  16.         {  
  17.             return View(lstEmployees);  
  18.         }  
  19.   
  20.     }  
Before moving further just compile the project once so that you can find the class inside the strongly typed view name dropdownlist when you try to add a view. Now try to add a view by right-clicking on the Index function. The view will be a strongly typed view since we are ing the list of Employees to the view. And also check the checkbox to use a layout or a master page. Here is the snapshot for it.

Razor Engine Working with Views in MVC

Here is the view code.
  1. @model IEnumerable<ViewsInDepth.Models.Employee>  
  2. @{  
  3.     ViewBag.Title = "Index";  
  4. }  
  5. <h2>  
  6.     Index</h2>  
  7. <div>  
  8.     <table>  
  9.         <thead>  
  10.             <tr>  
  11.                 <td>  
  12.                     EID  
  13.                 </td>  
  14.                 <td>  
  15.                     Name  
  16.                 </td>  
  17.                 <td>  
  18.                     Address  
  19.                 </td>  
  20.                 <td>  
  21.                     Designation  
  22.                 </td>  
  23.             </tr>  
  24.         </thead>  
  25.         <tbody>  
  26.             @foreach (var emp in Model)  
  27.             {  
  28.                 <tr>  
  29.                     <td>  
  30.                         @emp.EID  
  31.                     </td>  
  32.                     <td>  
  33.                         @emp.EName  
  34.                     </td>  
  35.                     <td>  
  36.                         @emp.EAdd  
  37.                     </td>  
  38.                     <td>  
  39.                         @emp.EDesignation  
  40.                     </td>  
  41.                 </tr>  
  42.             }  
  43.         </tbody>  
  44.     </table>  
  45. </div>  
Now whenever you run your application and try to access a view then what the Razor View Engine does is, it converts the View code into a C# class file. It will not convert the view to a C# class until and unless you try to access the view. The first request to the view will ask the Razor View Engine to convert it into C# class file. The advantage of doing that is it provides a faster response to the user since the files are already compiled and just need to be executed. To find a copy of the razor generated class file just press “%temp%” in the run command and click on the “Temporary ASP.NET Files” folder then click on the “root” folder view then check/view the files/folders according to the system time. Let's say you ran your application at 5 0'clock then there will a folder with an encrypted name created at 5 0'clock inside the root folder. Here is a snapshot of that.

Razor Engine Working with Views in MVC1

The one highlighted is my application folder that the razor engine created. Finding these files are a little difficult because they have encrypted names but you can find them using the strategy that we adopted that is by using system time. The advantage of compiling the view files into C# classes is that the access to the page/view is much faster because a compile file needs to be processed and the other benefit is that you are able to incorporate the C# code inside the View.

Here is the compiled file code. Again I'm saying you need to search a little to find the file because they have encrypted names. Here my file name is “App_Web_cp4ukq2j.0.cs”
  1. #pragma checksum "D:\Vishal\Mvc\ViewsInDepth\ViewsInDepth\Views\Home\Index.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "D0F32B1AF3DA597F11B766D5A7FB28D9C575671A"  
  2. //------------------------------------------------------------------------------  
  3. // <auto-generated>  
  4. //     This code was generated by a tool.  
  5. //     Runtime Version:4.0.30319.18408  
  6. //  
  7. //     Changes to this file may cause incorrect behavior and will be lost if  
  8. //     the code is regenerated.  
  9. // </auto-generated>  
  10. //------------------------------------------------------------------------------  
  11.   
  12. namespace ASP  
  13. {  
  14.     using System;  
  15.     using System.Collections.Generic;  
  16.     using System.IO;  
  17.     using System.Linq;  
  18.     using System.Net;  
  19.     using System.Web;  
  20.     using System.Web.Helpers;  
  21.     using System.Web.Security;  
  22.     using System.Web.UI;  
  23.     using System.Web.WebPages;  
  24.     using System.Web.Mvc;  
  25.     using System.Web.Mvc.Ajax;  
  26.     using System.Web.Mvc.Html;  
  27.     using System.Web.Optimization;  
  28.     using System.Web.Routing;  
  29.   
  30.   
  31.     public class _Page_Views_Home_Index_cshtml : System.Web.Mvc.WebViewPage<IEnumerable<ViewsInDepth.Models.Employee>>  
  32.     {  
  33.  
  34.         #line hidden  
  35.   
  36.         public _Page_Views_Home_Index_cshtml()  
  37.         {  
  38.         }  
  39.   
  40.         protected ASP.global_asax ApplicationInstance  
  41.         {  
  42.             get  
  43.             {  
  44.                 return ((ASP.global_asax)(Context.ApplicationInstance));  
  45.             }  
  46.         }  
  47.   
  48.         public override void Execute()  
  49.         {  
  50.  
  51.         #line 2 "D:\Vishal\Mvc\ViewsInDepth\ViewsInDepth\Views\Home\Index.cshtml"  
  52.   
  53.             ViewBag.Title = "Index";  
  54.  
  55.  
  56.         #line default  
  57.         #line hidden  
  58.             WriteLiteral(@"  
  59.                 <h2>Index</h2>  
  60.                 <div>  
  61.                     <table>  
  62.                         <thead>  
  63.                             <tr>  
  64.                                 <td>  
  65.                                     EID  
  66.                                 </td>  
  67.                                 <td>  
  68.                                     Name  
  69.                                 </td>  
  70.                                 <td>  
  71.                                     Designation  
  72.                                 </td>  
  73.                             </tr>  
  74.                     </thead>  
  75.                 <tbody>");  
  76.  
  77.  
  78.             #line 23 "D:\Vishal\Mvc\ViewsInDepth\ViewsInDepth\Views\Home\Index.cshtml"  
  79.  
  80.  
  81.             #line default  
  82.             #line hidden  
  83.  
  84.             #line 23 "D:\Vishal\Mvc\ViewsInDepth\ViewsInDepth\Views\Home\Index.cshtml"  
  85.             foreach (var emp in Model)  
  86.             {  
  87.  
  88.  
  89.             #line default  
  90.             #line hidden  
  91.                 WriteLiteral(@"                <tr>  
  92.                     <td>  
  93.                         emp.EID  
  94.                     </td>  
  95.                     <td>  
  96.                         emp.Name  
  97.                     </td>  
  98.                     <td>  
  99.                         emp.Designation  
  100.                     </td>  
  101.                 </tr>  
  102.             ");  
  103.  
  104.  
  105.             #line 36 "D:\Vishal\Mvc\ViewsInDepth\ViewsInDepth\Views\Home\Index.cshtml"  
  106.             }  
  107.  
  108.  
  109.         #line default  
  110.         #line hidden  
  111.             WriteLiteral("        </tbody>\r\n    </table>\r\n</div>\r\n");  
  112.   
  113.         }  
  114.     }  
  115. }  
Notes 
  1. Our class is inherited from System.Web.Mvc.WebViewPage<IEnumerable<ViewsInDepth.Models.Employee>>. Here IEnumerable<ViewsInDepth.Models.Employee> is there because we created a strongly typed view of IEnumerable<ViewsInDepth.Models.Employee>. If your view is strongly typed with some other types like int or string or any other custom class then that class will appear over here. That means the WebViewPage class is generic in nature.
  2. From the Excecute method we can see that the “WriteLiteral” function is used for writing HTML contents and the “Write” function is used for writing C# code. Both of these functions write the content to the TextWriter Object that in turn is used by the IView that is an interface for creation of the view.
  3. Also check the name of the C# class. It provides a full description of the view path.
  4. Also your View @ code is just written as C# code.