Click here to Skip to main content
Click here to Skip to main content

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

, 6 Aug 2014 CPOL
Rate this:
Please Sign up or sign in to vote.
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Sourav Kayal
Software Developer TIMKEN India research Institute
India India
I am software developer from INDIA, working in manufacturing domain. Beside my day to day development work, i like to learn new technology and update myself. I am passionate blogger and author in various technical community including dotnetfunda.com , c-sharpcorner.com and codeproject. My area of interest is modern web technology in Microsoft stack.
Follow on   LinkedIn

Comments and Discussions

 
GeneralMy vote of 5 PinprofessionalVolynsky Alex10-Aug-14 12:49 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150327.1 | Last Updated 6 Aug 2014
Article Copyright 2014 by Sourav Kayal
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid