MVC 3 Razor : Extending the View Engine

Written by John DeVight on 2011-May-11

rating: 0+x

Overview

I am working on an application used to generate different types and versions of the same document. The "document" model contains the same "core" information" shared across the different types of documents. Therefore, I needed to be able render different views for the same model depending on information found in the model as well as be able to support different versions of the same view as changes are made to the "document" from time to time. To accomplish this, I extended the MVC Razor View Engine and implemented code to check the model object to determine the type and version of the document and render the appropriate view.

Extending the Razor View Engine

To extend the Razor view engine, I created a class that derives from the RazorViewEngine class. I then overrode the CreateView method and implemented the desired logic.

Here is the sample code:

public class MyViewEngine : RazorViewEngine
{
    public MyViewEngine() : base()
    {
    }

    protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
    {
        // Check to see if the view that is being rendered is for a Document.
        if (controllerContext.Controller.ViewData.Model != null && 
            controllerContext.Controller.ViewData.Model.GetType() == typeof(Document))
        {
            Document doc = controllerContext.Controller.ViewData.Model as Document;
            // Get the type of document.
            string documentType = document.DocumentType;
            // Get the version of the document.
            int version = doc.Version;
            // Define the name of the view to render.
            string view = string.Format("{0}/{1}_{2}.cshtml", viewPath.Substring(0, viewPath.LastIndexOf('/')), 
                documentType, version);
            // Check to see if the view exists.
            if (System.IO.File.Exists(controllerContext.HttpContext.Request.MapPath(view)) == true)
            {
                viewPath = view;
            }
        }

        return base.CreateView(controllerContext, viewPath, masterPath);
    }
}

Registering the new View Engine

MVC 3 has 2 view engines. They are the RazorViewEngine and the WebFormViewEngine. When the application is started, an instance of each view engine is created and added to the System.Web.Mvc.ViewEngines.Engines ViewEngineCollection. Since I only wanted to use my view engine, in the Global.asax, Application_Start() method, I cleared the ViewEngines.Engines collection and added an instance of my view engine.

Here is the sample code:

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        // Code that appears in the Application_Start() be default.
        AreaRegistration.RegisterAllAreas();
        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);

        // Code that I implemented to register my view engine.
        ViewEngines.Engines.Clear();
        ViewEngines.Engines.Add(new EpxStudioViewEngine());
    }
}

That's all there is to it!

Support ASP.NET Wiki

If you like this page, click on the "Share on" links in the wikidot toolbar at the top of the page to share it with your friends.

Comments

Add a New Comment
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License