Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I implement a custom RazorViewEngine to find views in non-standard locations?

Tags:

I'm looking at implementing a custom RazorViewEngine. Basically I have two sites with effectively the same code base. The differences being that they look different. I want to override the standard view engine to make MVC look in two separate locations for it's views, layouts, etc. one for company A and another for Company B. Company A will contain the master views and company B's view will override these masters. So I want the View Engine to look in location B for a view, layout, master or partial if it finds it then return it, if it doesn't find it I want it to default to company A's views as the default. Obviously company A will only look in it's own folder.

Ok to the crux of the question: I've found this site: http://www.aspnetwiki.com/mvc-3-razor:extending-the-view-engine

First question, is this the best way to achieve this?

Second do I need to override the CreatePartial, CreateView, FindPartial and FindView methods?

Update

Ok I've figured out the second question myself, the Methods I want to override are CreateView and CreatePartialView as at this point it's built the view string and I can fiddle with it.

like image 348
Liam Avatar asked Mar 23 '12 11:03

Liam


1 Answers

Ok in the end I opted for an approach detailed here: http://weblogs.asp.net/imranbaloch/archive/2011/06/27/view-engine-with-dynamic-view-location.aspx

thanks to @Adriano for the answers and pointers but in the end I think this approach fits my needs better. The approach below allows me to keep the standard functionality but to create a new higher priority view location to be searched.

public class Travel2ViewEngine : RazorViewEngine {     protected BrandNameEnum BrandName;     private string[] _newAreaViewLocations = new string[] {         "~/Areas/{2}/%1Views/{1}/{0}.cshtml",         "~/Areas/{2}/%1Views/{1}/{0}.vbhtml",         "~/Areas/{2}/%1Views//Shared/{0}.cshtml",         "~/Areas/{2}/%1Views//Shared/{0}.vbhtml"     };      private string[] _newAreaMasterLocations = new string[] {         "~/Areas/{2}/%1Views/{1}/{0}.cshtml",         "~/Areas/{2}/%1Views/{1}/{0}.vbhtml",         "~/Areas/{2}/%1Views/Shared/{0}.cshtml",         "~/Areas/{2}/%1Views/Shared/{0}.vbhtml"     };      private string[] _newAreaPartialViewLocations = new string[] {         "~/Areas/{2}/%1Views/{1}/{0}.cshtml",         "~/Areas/{2}/%1Views/{1}/{0}.vbhtml",         "~/Areas/{2}/%1Views/Shared/{0}.cshtml",         "~/Areas/{2}/%1Views/Shared/{0}.vbhtml"     };      private string[] _newViewLocations = new string[] {         "~/%1Views/{1}/{0}.cshtml",         "~/%1Views/{1}/{0}.vbhtml",         "~/%1Views/Shared/{0}.cshtml",         "~/%1Views/Shared/{0}.vbhtml"     };      private string[] _newMasterLocations = new string[] {         "~/%1Views/{1}/{0}.cshtml",         "~/%1Views/{1}/{0}.vbhtml",         "~/%1Views/Shared/{0}.cshtml",         "~/%1Views/Shared/{0}.vbhtml"     };      private string[] _newPartialViewLocations = new string[] {         "~/%1Views/{1}/{0}.cshtml",         "~/%1Views/{1}/{0}.vbhtml",         "~/%1Views/Shared/{0}.cshtml",         "~/%1Views/Shared/{0}.vbhtml"     };      public Travel2ViewEngine()         : base()     {         Enum.TryParse<BrandNameEnum>(Travel2.WebUI.Properties.Settings.Default.BrandName, out BrandName);          AreaViewLocationFormats = AppendLocationFormats(_newAreaViewLocations, AreaViewLocationFormats);          AreaMasterLocationFormats = AppendLocationFormats(_newAreaMasterLocations, AreaMasterLocationFormats);          AreaPartialViewLocationFormats = AppendLocationFormats(_newAreaPartialViewLocations, AreaPartialViewLocationFormats);          ViewLocationFormats = AppendLocationFormats(_newViewLocations, ViewLocationFormats);          MasterLocationFormats = AppendLocationFormats(_newMasterLocations, MasterLocationFormats);          PartialViewLocationFormats = AppendLocationFormats(_newPartialViewLocations, PartialViewLocationFormats);     }      private string[] AppendLocationFormats(string[] newLocations, string[] defaultLocations)     {         List<string> viewLocations = new List<string>();         viewLocations.AddRange(newLocations);         viewLocations.AddRange(defaultLocations);         return viewLocations.ToArray();     }      protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)     {         return base.CreateView(controllerContext, viewPath.Replace("%1", BrandName.ToString()), masterPath);     }      protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)     {         return base.CreatePartialView(controllerContext, partialPath.Replace("%1", BrandName.ToString()));     }      protected override bool FileExists(ControllerContext controllerContext, string virtualPath)     {         return base.FileExists(controllerContext, virtualPath.Replace("%1", BrandName.ToString()));     } } 

then register in Gloabal.asax

protected void Application_Start(object sender, EventArgs e) {     RegisterRoutes(RouteTable.Routes);       //Register our customer view engine to control T2 and TBag views and over ridding     ViewEngines.Engines.Clear();     ViewEngines.Engines.Add(new Travel2ViewEngine()); } 
like image 85
Liam Avatar answered Oct 02 '22 14:10

Liam