我如何实现自定义的RazorViewEngine在非标准位置查找视图?

我正在寻找实现一个自定义的RazorViewEngine 。 基本上我有两个有效的代码相同的网站。 不同的是,他们看起来不同。 我想重写标准的视图引擎,使MVC在两个不同的位置查看它的视图,布局等。对于公司A,对于公司B来说,公司A将包含主视图,公司B的视图将覆盖这些主视图。 所以我想让视图引擎在位置B查看视图,布局,主要或部分,如果它发现它,然后返回它,如果它找不到它我希望它默认为公司A的视图作为默认值。 公司A显然只会查看自己的文件夹。

好的问题症结所在:我find了这个网站: http : //www.aspnetwiki.com/mvc-3-razor :extending-the-view-engine

第一个问题,这是实现这个目标的最好方法吗?

其次,我是否需要重写CreatePartialCreateViewFindPartialFindView方法?

更新

好吧,我已经想出了第二个问题,我想要重写的方法是CreateViewCreatePartialView因为在这一点上它构build了视图string,我可以摆弄它。

好吧,最后我select了一个详细的方法: http : //weblogs.asp.net/imranbaloch/archive/2011/06/27/view-engine-with-dynamic-view-location.aspx

感谢@Adriano的答案和指针,但最终我认为这种方法更适合我的需求。 下面的方法允许我保持标准function,但创build一个新的更高优先级的视图位置进行search。

 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())); } } 

然后在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()); } 

是的,这是方式,但你不需要重写该方法。 RazorViewEngine从VirtualPathProviderViewEngineinheritance,因此您可以使用它的属性来设置视图的位置。

有关示例,请参阅创build您的第一个MVC ViewEngine以及如何在 MVC 中设置默认路由(到区域) 。

这是我的答案:将此添加到您的global.ascx

  ViewEngines.Engines.Clear(); var customEngine = new RazorViewEngine(); customEngine.PartialViewLocationFormats = new string[] { "~/Views/{1}/{0}.cshtml", "~/Views/Shared/{0}.cshtml", "~/Views/Partial/{0}.cshtml", "~/Views/Partial/{1}/{0}.cshtml" }; customEngine.ViewLocationFormats = new string[] { "~/Views/{1}/{0}.cshtml", "~/Views/Shared/{0}.cshtml", "~/Views/Controller/{1}/{0}.cshtml" }; customEngine.MasterLocationFormats = new string[] { "~/Views/Shared/{0}.cshtml", "~/Views/Layout/{0}.cshtml" }; ViewEngines.Engines.Add(customEngine); 

这些是剃刀检查你的意见的文件夹。

让我知道这是否工作。