Asp.net mvc 是否可以为MVC Razor布局指定可搜索的位置格式?
在Razor中,加载局部视图时,可以只指定局部视图名称,Razor视图引擎将搜索RazorViewEngine.PartialViewLocationFormats: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 但是,在指定
@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中运行上面的代码。