MVC3 - 编译的Razor视图找不到_ViewStart [英] MVC3 - Compiled Razor view can't find _ViewStart

查看:433
本文介绍了MVC3 - 编译的Razor视图找不到_ViewStart的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用单独的类库编译剃刀的意见作为一种插件系统的MVC3。

I'm using compiled Razor views in separate class libraries as a sort of plugin system for MVC3.

我接着克里斯·范·德斯蒂德的这里只有偏离主要的部分有关添加引用,因为我装我的大会的在运行时。

I've followed the guide by Chris Van De Steed here and only deviated primarily on the part about adding references, as I'm loading my assemblys at runtime.

由于我在运行时加载程序集,我没有使用VirtualPathProviderViewEngine在中行库,并取而代之的是以RazorViewEngine实现我自己的ViewEngine。它通过重写viewPath在CreateView的插入适当的名称空间,这样的观点可以得到解决。

Because I'm loading assemblies at runtime, I'm not using the VirtualPathProviderViewEngine in the BoC library, and have instead implemented my own ViewEngine based on RazorViewEngine. It works by rewriting the viewPath in CreateView to insert the appropriate namespace so that the view can be resolved.

到目前为止好......我可以有不同的加载模块,如果它们共享相同的名称及其控制器也不会发生冲突。

So far so good... I can have different modules loaded, and their controllers won't collide if they share the same name.

我现在唯一的问题是,编译的意见,_ViewStart不叫。该_ViewStart工程的意见在主机MVC3项目,但是从插件组件加载的任何意见是没有找到。

The only problem I have now is that for compiled views, the _ViewStart is not called. The _ViewStart works for views in the host MVC3 project, but for any views loaded from the plugin assemblies it's not found.

我有一个路由的设置是这样的: -

I have a Route setup like this:-

RouteTable.Routes.MapRoute(
    string.Format("Plugin{0}Route", pluginName),
    string.Format(@"Plugin/{0}/{{controller}}/{{action}}", pluginName),
    new { },
    new string[] { string.Format("{0}.Controllers", pluginName) });

该视图引擎看起来是这样的: -

the ViewEngine looks like this:-

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被替换组件的名称)

(the %1 is replaced with the name of the assembly)

和组装与中行库这样的注册: -

and the assembly is registered with the BoC library like this:-

BoC.Web.Mvc.PrecompiledViews.ApplicationPartRegistry.Register(assembly, string.Format("/Plugin/{0}/", pluginName));

在该视图是从插件组件(本例中账户)加载,查看被发现,显示OK。但随后它会在这些位置的_ViewStart: -

When the view is loaded from a plugin assembly (in this example "accounts"), the view is found and displayed OK. But then it looks in these locations for the _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

但它看起来并不在〜/查看/共享/ _ViewStart.cshtml文件所在。

But it doesn't look in ~/Views/Shared/_ViewStart.cshtml where the file lives.

我试着改变这一切的位置格式在我的ViewEngine(AreaMasterLocationFormats,AreaPartialViewLocationFormats,AreaViewLocationFormats,MasterLocationFormats,PartialViewLocationFormats和ViewLocationFormats),但他们都不有所作为。

I've tried changing all the location formats in my ViewEngine (AreaMasterLocationFormats, AreaPartialViewLocationFormats, AreaViewLocationFormats, MasterLocationFormats, PartialViewLocationFormats and ViewLocationFormats) but none of them seem to make a difference.

我环顾四周,似乎<一个href=\"http://msdn.microsoft.com/en-us/library/system.web.webpages.startpage.getstartpage%28v=vs.99%29.aspx\"相对=nofollow> System.Web.WebPages.StartPage.GetStartPage 是负责寻找和视图返回起始页面,但我不能找到如何来控制它看起来的任何信息。

I've looked around and it seems that System.Web.WebPages.StartPage.GetStartPage is responsible for finding and returning the start page in a view, but I can't find any information on how to control where it looks.

我试过移动_ViewStart.cshtml到〜/ _ViewStart.cshtml(它看起来的地方之一),但是我立刻得到: -

I've tried moving the _ViewStart.cshtml to ~/_ViewStart.cshtml (one of the places it looks) however I immediately get:-

Unable to cast object of type 'ASP._Page__ViewStart_cshtml' to type 'System.Web.WebPages.StartPage'.

而根据我读过,是因为_ViewStart需要生活在/浏览次数

Which according to what I've read, is because the _ViewStart needs to live under /Views

我可以修改的地方MVC寻找一个_ViewStart?

Can I modify where MVC looks for a _ViewStart?

中行的库实现它自己的iView,并要求如下: -

The BoC library implements it's own IView, and calls the following:-

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

但在这种情况下ViewStartFileName只是_ViewStart和ViewStartFileExtensions只是CSHTML和vbhtml ......没有什么会控制在何处MVC要搜索的文件。

But in this case ViewStartFileName is just "_ViewStart" and ViewStartFileExtensions are just cshtml and vbhtml... nothing that would control where MVC should search for the file.

推荐答案

这是想法...(如,还没有尝试过。它是否行得通呢?不知道)

An idea... (as in, haven't tried it. Will it work? No idea)

也许看看从 RazorView 继承(或完全取代它,在考虑 - 因为我们会看到 - 你会被重写一个方法,就是批量之类的)。

Maybe have a look at inheriting from RazorView (or replacing it entirely, considering - as we'll see - you'll be rewriting the one method that is the bulk of the class).

RazorView StartPage.GetStartPage 是由它分配给的方式推出了 StartPageLookup 属性:

RazorView is where StartPage.GetStartPage is introduced by way of assigning it to a StartPageLookup property:

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

不幸的是,该委托财产是内部的,所以你不能只是简单地覆盖在你的派生类的构造函数。您可能,但是,能够覆盖 RazorView.RenderView ,这也正是它的使用的(MVC3源$ C ​​$ C,很多线路拆除,由我添加的换行符):

Unfortunately, that delegate property is internal, so you can't just overwrite it in your derived class' constructor. You may, however, be able to override RazorView.RenderView, which is where it's used (MVC3 source code, lots of lines removed, line-breaks added by me):

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通话用自己查找,然后替换的结果 CreateView的 CreatePartialView PluginRazorViewEngine PluginRazorView 类>。

Replace that StartPageLookup call with your own lookup, then replace the result of CreateView and CreatePartialView in your PluginRazorViewEngine with your new PluginRazorView class.

这篇关于MVC3 - 编译的Razor视图找不到_ViewStart的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆