andrewlocatelliwoodcock

Thoughts on Software

Custom View Engines: Registering custom extensions with your View Engine

leave a comment »


In my last post, I discussed how to tell ASP.Net MVC about the custom extensions for your fancy new custom views but how do you actually tell your new view engine that it should read them?

The first step of course is to create a custom view engine which is actually pretty simple: inherit from ViewEngine or another, existing view engine. In the examples I worked through in my MTUG presentation, I showed two custom view engines which both inherited from RazorViewEngine so that we could use standard Razor syntax, reuse the power of the Razor parser and yet use the output in novel ways: one custom view engine logged the HTML of every view it rendered, whilst the other actually rendered the view as a PDF file and returned a FileStreamResult rather than a standard Razor View.

In the example below our custom view engine, SampleViewEngine, inherits from ViewEngine. In the constructor, SampleViewEngine calls the ViewLocationFormats and PartialViewLocationFormats methods of the ViewEngine class and registers its interest in views ending in the extension .custom in the locations /Views/{Controller}/ and /Views/Shared{Controller}/.

 

public class SampleViewEngine: ViewEngine

{

public SampleViewEngine()

{

// This is where we tell MVC where to look for our files. This says

// to look for a file at “Views/{Controller}/{Action}.custom”

        base.ViewLocationFormats = new string[] { “~/Views/{1}/{0}.custom”, “~/Views/Shared/{0}.custom” };

        base.PartialViewLocationFormats = base.ViewLocationFormats;

}

/// <summary>

/// Overrides the ViewEngine’s CreateView method. Instantiates and returns a new SampleView

/// </summary>

/// <param name=”controllerContext”>ControllerContext of the calling Controller – contains ViewData, etc.</param>

/// <param name=”viewPath”>Path to the view</param>

/// <param name=”masterPath”>Path to the master file</param>

/// <returns>IView object that inherits from View</returns>

protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)

{

return new SampleView(controllerContext, viewPath, masterPath);

}

}

 

Note that the ViewLocationFormats and PartialViewLocationFormats methods accept not only the extension but also the location and name pattern of the view. They also accept an array of strings, which means that you can add as many locations, extensions and rules as you want. Just so we’re clear: your rules can reuse an existing extension but in a non-standard location as in the example below:

 

// reuse the .cshtml Razor extension but only recognize views that are in ~/Views/Reports/{Controller}/{Action} or ~/Views/Shared/Reports/{Controller}/{Action}

base.ViewLocationFormats = new string[] { “~/Views/Reports/{1}/{0}.cshtml”, “~/Views/Shared/Reports/{0}.cshtml” };

 

 

Written by andrewlocatelliwoodcock

October 20, 2011 at 20:55

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: