加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc-3 – MVC3 – 编译的Razor视图找不到_ViewStart

发布时间:2020-12-16 03:21:27 所属栏目:asp.Net 来源:网络整理
导读:我在单独的类库中使用编译的Razor视图作为MVC3的一种插件系统. 我遵循了Chris Van De Steed here的指南,并且主要是关于添加引用的部分,因为我在运行时加载我的程序集. 因为我在运行时加载程序集,所以我没有在BoC库中使用VirtualPathProviderViewEngine,而是
我在单独的类库中使用编译的Razor视图作为MVC3的一种插件系统.

我遵循了Chris Van De Steed here的指南,并且主要是关于添加引用的部分,因为我在运行时加载我的程序集.

因为我在运行时加载程序集,所以我没有在BoC库中使用VirtualPathProviderViewEngine,而是基于RazorViewEngine实现了我自己的ViewEngine.它的工作原理是在CreateView中重写viewPath以插入适当的命名空间,以便可以解析视图.

到目前为止一切都很好……我可以加载不同的模块,如果它们共享相同的名称,它们的控制器不会发生冲突.

我现在唯一的问题是,对于编译视图,不会调用_ViewStart. _ViewStart适用于主机MVC3项目中的视图,但是对于从插件程序集加载的任何视图,它都找不到.

我有这样的路线设置: –

RouteTable.Routes.MapRoute(
    string.Format("Plugin{0}Route",pluginName),string.Format(@"Plugin/{0}/{{controller}}/{{action}}",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));

从插件程序集加载视图时(在此示例中为“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

但它没有查看文件所在的?/ 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'.

根据我所读到的,是因为_ViewStart需要生活在/ Views下

我可以修改MVC查找_ViewStart的位置吗?

BoC库实现了它自己的IView,并调用以下内容: –

startPage = this.StartPageLookup(page,VirtualPathFactoryManagerViewEngine.ViewStartFileName,this.ViewStartFileExtensions);

但在这种情况下,ViewStartFileName只是“_ViewStart”而ViewStartFileExtensions只是cshtml和vbhtml ……没有什么可以控制MVC搜索文件的位置.

解决方法

一个想法……(因为,没有尝试过.它会起作用吗?不知道)

也许看看从RazorView继承(或完全替换它,考虑 – 正如我们将看到的 – 你将重写一个方法,这是该类的大部分).

RazorView是通过将其分配给StartPageLookup属性引入StartPage.GetStartPage的地方:

// In RazorView constructor:
StartPageLookup = StartPage.GetStartPage;

不幸的是,该委托属性是内部的,因此您不能在派生类的构造函数中覆盖它.但是,您可以覆盖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);
}

用您自己的查找替换该StartPageLookup调用,然后用您的新PluginRazorView类替换PluginRazorViewEngine中的CreateView和CreatePartialView的结果.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读