问题描述
我正在考虑实现一个自定义的 RazorViewEngine
.基本上,我有两个具有相同代码库的站点.不同之处在于它们看起来不同.我想覆盖标准视图引擎,使 MVC 在两个不同的位置查看它的视图、布局等.一个用于公司 A,另一个用于公司 B.公司 A 将包含主视图,公司 B 的视图将覆盖这些主视图.因此,我希望视图引擎在位置 B 中查找视图、布局、主视图或部分视图,如果找到它然后返回它,如果它没有找到它我希望它默认为公司 A 的视图作为默认值.显然,A 公司只会在它自己的文件夹中查看.
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.
好的,问题的关键:我找到了这个网站:http://www.aspnetwiki.com/mvc-3-razor:extending-the-view-engine
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?
第二,我是否需要覆盖 CreatePartial
、CreateView
、FindPartial
和 FindView
方法?
Second do I need to override the CreatePartial
, CreateView
, FindPartial
and FindView
methods?
更新
好的,我自己想出了第二个问题,我想覆盖的方法是 CreateView
和 CreatePartialView
因为此时它已经构建了视图字符串,我可以摆弄它.
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.
推荐答案
好吧,最后我选择了这里详述的方法:http://weblogs.asp.net/imranbaloch/archive/2011/06/27/view-engine-with-动态视图位置.aspx
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
感谢@Adriano 的回答和指点,但最终我认为这种方法更适合我的需求.下面的方法允许我保留标准功能,但创建一个新的更高优先级的视图位置以供搜索.
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()));
}
}
然后在 Gloabal.asax 中注册
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());
}
这篇关于如何实现自定义 RazorViewEngine 以在非标准位置查找视图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!