Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Performance Improvement in View Engine Setup and Implement Custom View Engine in ASP.NET MVC

0.00/5 (No votes)
6 Aug 2014 1  
In this article, we will understand custom view engine and view engine setup in ASP.NET MVC application

Introduction

As the title suggests, in this article, we will learn a bit of performance improvement by attaching right view engine in MVC and then we will learn to extend the existing Razor view engine and the implementation of our own view engine. So, let’s start with the view engine tuning part at first. We know that ActionResult is the super class of all result type of action and ViewResult is one of them. If we want to return a View, we can either explicitly specify the view name or may not mention. Now, view execution process is handled by view engine which performs in last part of MVC pipeline. At first, it decides whether the return result is ViewResult type or not and if the result is ViewResult type, then it views Engine’s responsibility to invoke the appropriate view. Generally, MVC framework uses two view engines by default, those are Web Form view engine and Razor view engine and MVC framework searches for Web Form view engine at first, if not present then Razor view engine. So, in theory, whenever MVC framework wants to invoke a view, if search for Web Form view engine at first then search for Razor view engine, even if we use only Razor view engine in application. So, let’s see it in action. Here is the controller which contains Index() action and we are trying to return Test view which is not available in the application.

      public class TestController : Controller
      {
        public ActionResult Index()
        {
            return View("Test");
        }
    }

Obviously, we should see the below screen, because we don’t have the view at all. If we check the search step closely, then we will see that MVC framework is searching .aspx page at first, then .cshtml and all, so the Web Form view is performing at first then Razor view.

As we said earlier, this will slow down the view execution process, ok. Let’s solve the problem. We know that MVC is highly customized and configurabled. Now, we will detach Web Form view engine from MVC pipeline and we will attach only Razor view Engine then the framework will not search for Web Form view at the time of execution. The process is very simple. Just open Global.asax page of application and modify the code accordingly.

public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            RouteConfig.RegisterRoutes(RouteTable.Routes);

            //Remove all view engine
            ViewEngines.Engines.Clear();

            //Add Razor view Engine
            ViewEngines.Engines.Add(new RazorViewEngine());

            Bootstrapper.Initialise();
        }
    }

Here, we are clearing all view engines from MVC pipeline and then we are registering only Razor view engine. Now, if we run the same application, we will find below output and we are seeing that now MVC framework is not searching for .aspx page.

Customize the Razor view Engine

Now, there is another small problem in application. We are seeing that Razor view engine is searching both for vbhtml and cshtml page. Now, it’s very much common in application that you might use single programming language in View , either C# or VB. So, here we can again customize the existing Razor view engine to let it search only for cshtml page or vbhtml page. So, just create one class and inherit it from RazorViewEngine class. Here is the example implementation:

public class CSharpRazorViewEngine : RazorViewEngine
    {
        public CSharpRazorViewEngine()
        {
            AreaViewLocationFormats = new[]
             {
             "~/Areas/{2}/Views/{1}/{0}.cshtml",
             "~/Areas/{2}/Views/Shared/{0}.cshtml"
             };
                        AreaMasterLocationFormats = new[]
             {
             "~/Areas/{2}/Views/{1}/{0}.cshtml",
             "~/Areas/{2}/Views/Shared/{0}.cshtml"
             };
                        AreaPartialViewLocationFormats = new[]
             {
             "~/Areas/{2}/Views/{1}/{0}.cshtml",
             "~/Areas/{2}/Views/Shared/{0}.cshtml"
             };
                        ViewLocationFormats = new[]
             {
             "~/Views/{1}/{0}.cshtml",
             "~/Views/Shared/{0}.cshtml"
             };
                        MasterLocationFormats = new[]
             {
             "~/Views/{1}/{0}.cshtml",
             "~/Views/Shared/{0}.cshtml"
             };
                        PartialViewLocationFormats = new[]
             {
             "~/Views/{1}/{0}.cshtml",
             "~/Views/Shared/{0}.cshtml"
             };
        }
    }

Now, we have to register the view engine in MVC pipeline. Just modify the Global.asax file accordingly.

public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            RouteConfig.RegisterRoutes(RouteTable.Routes);

            //Remove all view engine
            ViewEngines.Engines.Clear();

            //Add Custom view Engine Derived from Razor
            ViewEngines.Engines.Add(new CSharpRazorViewEngine());

            Bootstrapper.Initialise();
        }
    }

Now, if we run the application, we will see that the custom view Engine is searching for .cshtml page only.

Fine, we have learned to customize the view engine to improve performance of MVC application. Now, we will build our own view engine and we will use the engine in place of existing Web Form view or Razor view.

Implement Custom View Engine

To implement our own view engine, we have to implement IViewEngine in our own class. The IViewEngine contains three methods.

  • FindPartialView: This method will search for partial view if there is any partial view call in main view.
  • FindView: This method will search for main view.
  • ReleaseView: After execution of view, we can implement disposing activity of our custom view class.

Here, I have implemented IViewEngine interface in “MyViewEngine” class. Have a look at the below code:

 public class MyViewEngine : IViewEngine 
    {
        public ViewEngineResult FindPartialView
        (ControllerContext controllerContext, string partialViewName, bool useCache)
        {
            throw new NotImplementedException();
        }

        public ViewEngineResult FindView(ControllerContext controllerContext,
            string viewName, string masterName, bool useCache)
        {
            if (viewName.Contains("myView")) 
            {
                return new ViewEngineResult(new myCustomView(),this);
            }
            else
                return new ViewEngineResult(new string[] {"No View found, please provide correct name"});
        }

        public void ReleaseView(ControllerContext controllerContext, IView view)
        {
            
        }
    }

So, we have built our own view engine, now we have to build our own view. To build our own view, we have to implement IView interface in our own class. In this example, I have implemented IView interface in myCustomView class. The IView contains one and only one method called Render where we can implement the rendering mechanism. In this example, we are just printing string.

  public class myCustomView : IView
    {
        public void Render(ViewContext viewContext, System.IO.TextWriter writer)
        {
            writer.Write("Data from custom view");
        }
    }

Register the Custom View

This is one obvious process we need to follow. We have to register the custom view in MVC pipeline. Just modify the Global.asax page accordingly.

protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            RouteConfig.RegisterRoutes(RouteTable.Routes);

            //Remove all view engine
            ViewEngines.Engines.Clear();

            //Attach custom view in pipeline
            ViewEngines.Engines.Add(new MyViewEngine());
                        
            Bootstrapper.Initialise();
        }

Now, we will implement controller and we will call our custom view. Here I have specified the action name as myView.

public class TestController : Controller
    {
        public ActionResult myView()
        {
            return View();
        }
    }

And once we run the application and try to hit myView() action, we will see that the custom string has appeared on the screen.

Border Line

In this example, we have learned to configure view engine in MVC application and also learned to implement custom view engine. Hope this article will give you a better understanding of view execution process in MVC application.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here