You're looking for a Custom View Engine which is similar to this Stack Overflow question. But your use case is different since it would entail differing paths depending on which tenant loaded your application.
I found http://weblogs.asp.net/imranbaloch/archive/2011/06/27/view-engine-with-dynamic-view-location.aspx which I think would fit your situation nicely.
public class MyRazorViewEngine : RazorViewEngine
{
public MyRazorViewEngine() : base()
{
AreaViewLocationFormats = new[] {
"~/Areas/{2}/Views/%1/{1}/{0}.cshtml",
"~/Areas/{2}/Views/%1/{1}/{0}.vbhtml",
"~/Areas/{2}/Views/%1/Shared/{0}.cshtml",
"~/Areas/{2}/Views/%1/Shared/{0}.vbhtml"
};
AreaMasterLocationFormats = new[] {
"~/Areas/{2}/Views/%1/{1}/{0}.cshtml",
"~/Areas/{2}/Views/%1/{1}/{0}.vbhtml",
"~/Areas/{2}/Views/%1/Shared/{0}.cshtml",
"~/Areas/{2}/Views/%1/Shared/{0}.vbhtml"
};
AreaPartialViewLocationFormats = new[] {
"~/Areas/{2}/Views/%1/{1}/{0}.cshtml",
"~/Areas/{2}/Views/%1/{1}/{0}.vbhtml",
"~/Areas/{2}/Views/%1/Shared/{0}.cshtml",
"~/Areas/{2}/Views/%1/Shared/{0}.vbhtml"
};
ViewLocationFormats = new[] {
"~/Views/%1/{1}/{0}.cshtml",
"~/Views/%1/{1}/{0}.vbhtml",
"~/Views/%1/Shared/{0}.cshtml",
"~/Views/%1/Shared/{0}.vbhtml"
};
MasterLocationFormats = new[] {
"~/Views/%1/{1}/{0}.cshtml",
"~/Views/%1/{1}/{0}.vbhtml",
"~/Views/%1/Shared/{0}.cshtml",
"~/Views/%1/Shared/{0}.vbhtml"
};
PartialViewLocationFormats = new[] {
"~/Views/%1/{1}/{0}.cshtml",
"~/Views/%1/{1}/{0}.vbhtml",
"~/Views/%1/Shared/{0}.cshtml",
"~/Views/%1/Shared/{0}.vbhtml"
};
}
protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
{
var nameSpace = controllerContext.Controller.GetType().Namespace;
return base.CreatePartialView(controllerContext, partialPath.Replace("%1", nameSpace));
}
protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
{
var nameSpace = controllerContext.Controller.GetType().Namespace;
return base.CreateView(controllerContext, viewPath.Replace("%1", nameSpace), masterPath.Replace("%1", nameSpace));
}
protected override bool FileExists(ControllerContext controllerContext, string virtualPath)
{
var nameSpace = controllerContext.Controller.GetType().Namespace;
return base.FileExists(controllerContext, virtualPath.Replace("%1", nameSpace));
}
}
Instead of replacing the %1
with the namespace, replace it with your customer name. And then add the base path to the end of all the locations to ensure the base path is always found last.
Make sure you add the view engine to the ViewEngines.Engines
collection as well.