我在单独的类库中使用编译的 Razor 视图作为 MVC3 的一种插件系统。
我遵循 Chris Van De Steed 的指南here http://www.chrisvandesteeg.nl/2010/11/22/embedding-pre-compiled-razor-views-in-your-dll/并且仅在添加引用的部分主要有所偏差,因为我在运行时加载程序集。
因为我在运行时加载程序集,所以我没有使用 BoC 库中的 VirtualPathProviderViewEngine,而是基于 RazorViewEngine 实现了我自己的 ViewEngine。它的工作原理是重写CreateView中的viewPath以插入适当的命名空间,以便可以解析视图。
到目前为止一切顺利...我可以加载不同的模块,并且如果它们共享相同的名称,它们的控制器就不会发生冲突。
我现在遇到的唯一问题是,对于编译视图,未调用 _ViewStart。 _ViewStart 适用于主机 MVC3 项目中的视图,但对于从插件程序集加载的任何视图,找不到它。
我有这样的路线设置:-
RouteTable.Routes.MapRoute(
string.Format("Plugin{0}Route", pluginName),
string.Format(@"Plugin/{0}/{{controller}}/{{action}}", pluginName),
new { },
new string[] { string.Format("{0}.Controllers", pluginName) });
ViewEngine 看起来像这样:-
public class PluginRazorViewEngine : RazorViewEngine
{
public PluginRazorViewEngine() : base()
{
ViewLocationFormats = new[]
{
"~/Plugin/%1/Views/{1}/{0}.cshtml",
"~/Plugin/%1/Views/{1}/{0}.vbhtml",
"~/Plugin/%1/Views/Shared/{0}.cshtml",
"~/Plugin/%1/Views/Shared/{0}.vbhtml",
"~/Views/{1}/{0}.cshtml",
"~/Views/{1}/{0}.vbhtml",
"~/Views/Shared/{0}.cshtml",
"~/Views/Shared/{0}.vbhtml"
};
(%1 替换为程序集的名称)
并且该程序集已在 BoC 库中注册,如下所示:-
BoC.Web.Mvc.PrecompiledViews.ApplicationPartRegistry.Register(assembly, string.Format("/Plugin/{0}/", pluginName));
当从插件程序集(在本例中为“帐户”)加载视图时,会找到该视图并正常显示。但随后它会在这些位置查找 _ViewStart:-
~/plugin/accounts/views/invoice/_viewstart.cshtml
~/plugin/accounts/views/invoice/_viewstart.vbhtml
~/plugin/accounts/views/_viewstart.cshtml
~/plugin/accounts/views/_viewstart.vbhtml
~/plugin/accounts/_viewstart.cshtml
~/plugin/accounts/_viewstart.vbhtml
~/plugin/_viewstart.cshtml
~/plugin/_viewstart.vbhtml
~/_viewstart.cshtml
~/_viewstart.vbhtml
但它不会在文件所在的 ~/Views/Shared/_ViewStart.cshtml 中查找。
我尝试更改 ViewEngine 中的所有位置格式(AreaMasterLocationFormats、AreaPartialViewLocationFormats、AreaViewLocationFormats、MasterLocationFormats、PartialViewLocationFormats 和 ViewLocationFormats),但它们似乎都没有效果。
我环顾四周,似乎System.Web.WebPages.StartPage.获取起始页 http://msdn.microsoft.com/en-us/library/system.web.webpages.startpage.getstartpage%28v=vs.99%29.aspx负责在视图中查找并返回起始页,但我找不到任何有关如何控制其外观的信息。
我尝试将 _ViewStart.cshtml 移动到 ~/_ViewStart.cshtml (它看起来的地方之一),但我立即得到:-
Unable to cast object of type 'ASP._Page__ViewStart_cshtml' to type 'System.Web.WebPages.StartPage'.
根据我读到的内容,是因为 _ViewStart 需要位于 /Views 下
我可以修改 MVC 查找 _ViewStart 的位置吗?
BoC 库实现了它自己的 IView,并调用以下内容:-
startPage = this.StartPageLookup(page, VirtualPathFactoryManagerViewEngine.ViewStartFileName, this.ViewStartFileExtensions);
但在本例中,ViewStartFileName 只是“_ViewStart”,ViewStartFileExtensions 只是 cshtml 和 vbhtml...没有任何内容可以控制 MVC 应在何处搜索文件。