Configuring the View Search Location by Customizing Razor in ASP.Net MVC 4

Continuing with my previous example, we will try to customize how the default Razor View Engine works. I request that you go through my previous article if you haven't, here is the link:

How Razor Engine Works With Views in MVC 4

Whenever a request comes for a specific view the Razor Engine tries to find the view in the specific locations. For example let's say the controller name is "SimpleController" and the action name is “Index” then the Razor Engine will try to find the view in the following locations.

~/views/Simple/Index.cshtml
~/views/Simple/Index.vbhtml
~/views/Shared/Index.cshtml
~/views/Shared/Index.vbhtml

If you have created an area in your application then a search will be done in the following locations also:

~/Areas/AreaName/Views/Simple/Index.cshtml
~/Areas/AreaName/Views/Simple/Index.vbhmtl
~/Areas/AreaName/Views/Shared/Index.cshtml
~/Areas/AreaName/Views/Shared/Index.vbhtml

NOTE: The Razor View Engine will search for both of the pages/views, in other words it will search for the view with a .cshtml extension, .vbhtml extension as well as with .aspx and .ascx extension.

The conventions that the Razor View Engine follows are the following:

1. For searching views, weforms, master pages or partial views or user controls:

~/Views/{1}/{0}.cshtml
~/Views/{1}/{0}.vbhtml
~/Views/Shared/{0}.cshtml
~/Views/Shared/{0}.vbhtml

2. For searching views, weforms, master pages or partial views or user controls inside the area:

~/Areas/{2}/Views/{1}/{0}.cshtml
~/Areas/{2}/Views /{1}/{0}.vbhmtl
~/Areas/{2}/Views /Shared/{0}.cshtml
~/Areas/{2}/Views /Shared/{0}.vbhtml

NOTE: The notations used as {0}, {1} and {2} are basically like a placeholder; each one will hold a value at runtime.

{0} is for holding view name
{1} is for holding controller name
{2} is for holding area name

This is the default way to search for a specific view whenever a request arises from the user. You can however customize how the Razor Engine works by creating your own view engine. For creation of a new view engine your class needs to derive from the “RazorViewEngine” class or you can also implement the “IView” interface.

Let's move on to the example. I'm adding a new folder to my application with the name “Concrete” and inside that I'm adding a class with “CustomizeViewEngine.cs”.
By using this class we'll try to customize how views are searched by the Razor Engine. We've added a “special” folder inside the views folder and also added a view with the name “Special” that will be called whenever a request comes for that view.

Here is the code snippet for the Special View:

  1. @using ViewsInDepth.Models  
  2. @model IEnumerable<Employee>  
  3. @{  
  4.     ViewBag.Title = "Special";  
  5. }  
  6. <h2>  
  7.     Special</h2>  
  8. <table>  
  9.     <thead>  
  10.         <tr>  
  11.             <td>  
  12.                 Emp ID  
  13.             </td>  
  14.             <td>  
  15.                 Name  
  16.             </td>  
  17.         </tr>  
  18.     </thead>  
  19.     <tbody>  
  20.         @foreach (var emp in Model)  
  21.         {  
  22.             <tr>  
  23.                 <td>  
  24.                     @emp.EID  
  25.                 </td>  
  26.                 <td>  
  27.                     @emp.EName  
  28.                 </td>  
  29.             </tr>  
  30.         }  
  31.     </tbody>  
  32. </table>  

 

Create a new action method inside the Home Controller with the name Special. Here is the code snippet:

  1. public ActionResult Special()  
  2. {  
  3.    return View(lstEmployees);  
  4. }  

 

Here is the code snippet for the CustomizeViewEngine.cs file:

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5. using System.Web.Mvc;  
  6.    
  7. namespace ViewsInDepth.Concrete  
  8. {  
  9.     public class CustomizeViewEngine : RazorViewEngine  
  10.     {  
  11.         public CustomizeViewEngine()  
  12.         {  
  13.             //here we are resetting the ViewLocationFormats  
  14.             ViewLocationFormats = new string[] { "~/Views/{1}/{0}.cshtml""~/Views/special/{0}.cshtml" };  
  15.         }  
  16.     }  
  17. }  

 

Once our customize view engine is ready we can make use of it, we just need to register it with our application. For doing this we need to make an entry in the global.asax file.

The following are the entries:

  1. //first clear the default view engines  
  2. ViewEngines.Engines.Clear();  
  3. //now register our customize view engine with the application  
  4. ViewEngines.Engines.Add(new CustomizeViewEngine());  

 

It is now time to test the application by running it. Enter the URL /Home/Special and you'll find that your view is displayed from the special folder inside the views. Now the views inside the shared folders are not considered.

Next Recommended Readings