Asp.net mvc 是否可以为MVC Razor布局指定可搜索的位置格式?

Asp.net mvc 是否可以为MVC Razor布局指定可搜索的位置格式?,asp.net-mvc,Asp.net Mvc,在Razor中,加载局部视图时,可以只指定局部视图名称,Razor视图引擎将搜索RazorViewEngine.PartialViewLocationFormats: @Html.RenderPartial("_PartialView", Model); 将实际搜索视图引擎中PartialViewLocationFormats中指定的位置,例如 ~/Views/Home/_PartialView.cshtml ~/Views/Shared/_PartialView.cshtml 但是,在指定

在Razor中,加载局部视图时,可以只指定局部视图名称,Razor视图引擎将搜索RazorViewEngine.PartialViewLocationFormats:

@Html.RenderPartial("_PartialView", Model);
将实际搜索视图引擎中PartialViewLocationFormats中指定的位置,例如

~/Views/Home/_PartialView.cshtml
~/Views/Shared/_PartialView.cshtml
但是,在指定布局时,我似乎被迫指定布局的特定路径:

@Layout = "~/Views/Shared/MyLayout.cshtml";
我想做的是仅按名称指定布局,并通过搜索常见位置列表找到实际布局:

@Layout = "MyLayout";
…但我找不到任何设施可以这样做。由于找不到任何有关此的文档,我尝试使用设置RazorViewEngine.MasterLocationFormats,但在定位布局时不使用此属性


有人知道怎么做吗?

我尝试了几种不同的方法,却找不到一种方法来做你想做的事。但是,您可以将布局留空,然后使用_ViewStart.cshtml文件为每个页面分配布局,使用ViewBag属性是很重要的

因此,如果您有一个枚举(例如),并将CustomLayout的dynamic viewbag属性设置为该枚举的值,则可以使用_ViewStart文件执行类似操作

@{  
    MvcApplication12.Controllers.CustomLayouts customLayout = this.ViewContext.Controller.ViewBag.CustomLayout;

    switch (customLayout)
    {
        case MvcApplication12.Controllers.CustomLayouts.Blue: Layout = "~/Views/Shared/Blue.cshtml"; break;
        case MvcApplication12.Controllers.CustomLayouts.Green: Layout = "~/Views/Shared/Green.cshtml"; break;
        case MvcApplication12.Controllers.CustomLayouts.Default:
        default: Layout = "~/Views/Shared/Default.cshtml"; break;
    }   
}

不确定这是否有帮助。

最近我遇到了一个类似的问题,在一个使用自定义视图引擎首先搜索主题位置的主题应用程序中,我试图覆盖一些主文件。强制布局位置通过ViewEngine的FindView的一种方法是在返回时在控制器操作中指定主视图的名称:

return View("myView", "myViewMaster");
但是,如果“myViewMaster”也有一个布局(嵌套布局),则此方法不适用于嵌套布局。到目前为止,我的最佳解决方案是在视图中直接调用视图引擎:

@{
    Layout = (ViewEngines.Engines.FindView(this.ViewContext.Controller.ControllerContext, "myViewMaster", "").View as RazorView).ViewPath;
}
这是可行的,但肯定可以封装在扩展方法中,以避免重复和抽象代码


希望有帮助

我从@sowee15获得了公认的答案,并添加了一个扩展方法来帮助总结:

using System;
using System.Web.Mvc;

namespace MyApp.Classes
{
    public static class ViewEngineCollectionExtensions
    {
        public static string FindViewPath(this ViewEngineCollection viewEngines, ControllerContext controllerContext, string viewName, string masterName = null)
        {
            var viewResult = ViewEngines.Engines.FindView(controllerContext, viewName, masterName ?? string.Empty);
            if(viewResult == null)
                throw new Exception(string.Format("The specified view {0} could not be found.", viewName));

            var view = viewResult.View as RazorView;
            if(viewResult == null)
                throw new Exception(string.Format("The specified view {0} must be a Razor view.", viewName));

            return view.ViewPath;
        }
    }
}
然后,您可以从视图或viewstart.cshtml调用extension,如下所示:

@{
    Layout = ViewEngines.Engines.FindViewPath(ViewContext.Controller.ControllerContext, "_PopupLayout");
}

谢谢,这对我有用。虽然已经一年了,有没有人找到一个更好的解决方案,让我只说Layout=“Main2Col.cshmtl”而不是需要那整行代码?创建自己的WebViewPage派生类,并使所有视图都继承它。在其中,重写布局并在get中运行上面的代码。