【问题标题】:How do I make MVC look for razor and webforms views in the Views/Shared folder last?如何让 MVC 最后在 Views/Shared 文件夹中查找 razor 和 webforms 视图?
【发布时间】:2011-09-13 03:35:09
【问题描述】:

我有一个使用经典 Web 表单视图的旧 ASP.NET MVC 应用程序。作为一个实验,我们已经开始混合一些剃刀视图。不幸的是,在哪里可以找到所需视图的默认优先级不是我想要的。 MVC 首先在 /Views/ControllerName 文件夹中查找 aspx 和 ascx 文件。然后它移动到您的 /Views/Shared 以获取 aspx 和 ascx 文件。然后它开始寻找 .cshtml 和 .vbhtml 文件。我想要的是它在用尽 /Views/ControllerName 文件夹中的所有可能性之前不要进入 Shared 文件夹。我该怎么做?

--- 更新 ---

这里有一些额外的信息可能有助于解释我所追求的。默认情况下,我得到这个搜索顺序:

~/Views/Home/Index.aspx
~/Views/Home/Index.ascx
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
~/Views/Home/Index.cshtml
~/Views/Home/Index.vbhtml
~/Views/Shared/Index.cshtml
~/Views/Shared/Index.vbhtml 

我想要的是这个:

~/Views/Home/Index.aspx
~/Views/Home/Index.ascx
~/Views/Home/Index.cshtml
~/Views/Home/Index.vbhtml
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
~/Views/Shared/Index.cshtml
~/Views/Shared/Index.vbhtml

换句话说,它不应该在完全搜索 /Views/ControllerName 文件夹之前搜索 Shared。

【问题讨论】:

    标签: c# asp.net-mvc-3 razor


    【解决方案1】:

    您可以在 global.asax.cs 文件中配置视图引擎的优先级

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
    
            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);
    
            ViewEngines.Engines.Clear();
            ViewEngines.Engines.Add(new RazorViewEngine());
            ViewEngines.Engines.Add(new WebFormViewEngine());
        }
    

    【讨论】:

    • 这只是扭转了问题。它首先将顺序从 .aspx/.ascx 更改为 .cshtml/.vbhtml。但它仍然会在 Shared 文件夹中查找,然后它会耗尽 /Views/ControllerName 文件夹中的所有可能性,所以这不是我想要的。
    • @mattmc3 要实现您的要求,您必须编写一个新的视图引擎,它是RazorViewEngineWebFormViewEngine 的代理。
    【解决方案2】:

    玩弄了一下之后,我能够通过一个简单的 Fluent API 实现我想要的。扩展方法从每个视图引擎中删除了我不想要的搜索位置。搜索位置存储在.ViewLocationFormats.PartialViewLocationFormats 字符串数组中。因此,这是从这些数组中删除不需要的项目的 fluent API:

    public static class BuildManagerViewEngineFluentExtensions {
        public static BuildManagerViewEngine ControllerViews(this BuildManagerViewEngine engine) {
            return FilterViewLocations(engine, x => x.Contains("/Views/Shared/") == false);
        }
    
        public static BuildManagerViewEngine SharedViews(this BuildManagerViewEngine engine) {
            return FilterViewLocations(engine, x => x.Contains("/Views/Shared/") == true);
        }
    
        private static BuildManagerViewEngine FilterViewLocations(BuildManagerViewEngine engine, Func<string, bool> whereClause) {
            engine.ViewLocationFormats = engine.ViewLocationFormats.Where(whereClause).ToArray();
            engine.PartialViewLocationFormats = engine.PartialViewLocationFormats.Where(whereClause).ToArray();
            return engine;
        }
    }
    

    然后,在我的 global.asax 中,我将以下行添加到 protected void Application_Start()

    ViewEngines.Engines.Clear();
    ViewEngines.Engines.Add(new RazorViewEngine().ControllerViews());
    ViewEngines.Engines.Add(new WebFormViewEngine().ControllerViews());
    ViewEngines.Engines.Add(new RazorViewEngine().SharedViews());
    ViewEngines.Engines.Add(new WebFormViewEngine().SharedViews()); 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-07
      • 1970-01-01
      • 1970-01-01
      • 2011-08-16
      • 1970-01-01
      • 2010-11-08
      • 1970-01-01
      相关资源
      最近更新 更多