Ale*_*eks 5 plugins razor asp.net-mvc-3
我在单独的类库中使用编译的Razor视图作为MVC3的一种插件系统.
我接着克里斯·范·德斯蒂德导向这里,只有主要偏离的部分有关添加引用,因为我装我的组装件在运行时.
因为我在运行时加载程序集,所以我没有在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) });
Run Code Online (Sandbox Code Playgroud)
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"
};
Run Code Online (Sandbox Code Playgroud)
(%1被替换为程序集的名称)
并且汇编在BoC库中注册如下: -
BoC.Web.Mvc.PrecompiledViews.ApplicationPartRegistry.Register(assembly, string.Format("/Plugin/{0}/", pluginName));
Run Code Online (Sandbox Code Playgroud)
从插件程序集加载视图时(在此示例中为"accounts"),查找并显示视图.但是它会在这些位置查找_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
Run Code Online (Sandbox Code Playgroud)
但它没有查看文件所在的〜/ Views/Shared/_ViewStart.cshtml.
我试过改变我的ViewEngine中的所有位置格式(AreaMasterLocationFormats,AreaPartialViewLocationFormats,AreaViewLocationFormats,MasterLocationFormats,PartialViewLocationFormats和ViewLocationFormats),但它们似乎没有任何区别.
我环顾四周,似乎System.Web.WebPages.StartPage.GetStartPage负责查找并返回视图中的起始页面,但我找不到任何有关如何控制它的外观的信息.
我已经尝试将_ViewStart.cshtml移动到〜/ _ViewStart.cshtml(它看起来的地方之一)但是我马上得到: -
Unable to cast object of type 'ASP._Page__ViewStart_cshtml' to type 'System.Web.WebPages.StartPage'.
Run Code Online (Sandbox Code Playgroud)
根据我所读到的,是因为_ViewStart需要生活在/ Views下
我可以修改MVC查找_ViewStart的位置吗?
BoC库实现了它自己的IView,并调用以下内容:
startPage = this.StartPageLookup(page, VirtualPathFactoryManagerViewEngine.ViewStartFileName, this.ViewStartFileExtensions);
Run Code Online (Sandbox Code Playgroud)
但在这种情况下,ViewStartFileName只是"_ViewStart"而ViewStartFileExtensions只是cshtml和vbhtml ......没有什么可以控制MVC搜索文件的位置.
一个想法......(例如,还没有尝试过。它会起作用吗?不知道)
也许看看继承RazorView(或完全替换它,考虑到 - 正如我们将看到的 - 您将重写作为类的大部分的一个方法)。
RazorView是StartPage.GetStartPage通过将其分配给StartPageLookup属性来引入的:
// In RazorView constructor:
StartPageLookup = StartPage.GetStartPage;
Run Code Online (Sandbox Code Playgroud)
不幸的是,该委托属性是内部的,因此您不能在派生类的构造函数中覆盖它。但是,您可以覆盖它的使用RazorView.RenderView位置(MVC3源代码,删除了很多行,我添加了换行符):
protected override void RenderView(ViewContext viewContext, TextWriter writer,
object instance)
{
// [SNIP]
WebPageRenderingBase startPage = null;
if (RunViewStartPages) {
// HERE IT IS:
startPage = StartPageLookup(
webViewPage,
RazorViewEngine.ViewStartFileName,
ViewStartFileExtensions
);
}
webViewPage.ExecutePageHierarchy(
new WebPageContext(
context: viewContext.HttpContext,
page: null,
model: null),
writer, startPage);
}
Run Code Online (Sandbox Code Playgroud)
CreateView将 StartPageLookup 调用替换为您自己的查找,然后将和的结果替换为CreatePartialView您PluginRazorViewEngine的新PluginRazorView类。
| 归档时间: |
|
| 查看次数: |
2827 次 |
| 最近记录: |