我想通过基本控制器或属性中的代码设置默认 Razor 布局。文档中提到这是可能的,但我无法弄清楚它是如何完成的。
我知道 View 方法有 masterPage 参数可用,但我希望控制器返回的所有视图都自动设置此值。
不,我不能为此使用 _ViewStart,因为我的视图将在不同的地方(这不是正常的 MVC 站点配置)。
谢谢
我想通过基本控制器或属性中的代码设置默认 Razor 布局。文档中提到这是可能的,但我无法弄清楚它是如何完成的。
我知道 View 方法有 masterPage 参数可用,但我希望控制器返回的所有视图都自动设置此值。
不,我不能为此使用 _ViewStart,因为我的视图将在不同的地方(这不是正常的 MVC 站点配置)。
谢谢
我想你可以写一个 ActionFilter 像......
public class YourCustomLayoutAttribute : ActionFilterAttribute, IResultFilter
{
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
var viewResult = filterContext.Result as ViewResult;
if(viewResult != null)
{
// switch the layout
// I assume Razor will follow convention and take the "MasterName" property and change the layout based on that.
viewResult.MasterName = "CustomLayout";
}
}
}
我只是在没有编译器的情况下直接编写了这段代码,所以它可能无法编译,但你可能明白了。我认为 IResultFilter 是您想要的正确接口,它具有在呈现视图之前执行的方法。如果这是正确的,您应该能够修改即将实时呈现的视图的 MasterName。
这将是控制器代码的使用。
[YourCustomLayout] // this should trigger your custom action result for all actions
public class MyController : Controller
{
public ActionResult Index()
{
return View("Index", "MainLayout"); // even if you were to use the overload to set a master, the action result should override it as it executes later in the pipeline.
}
}
我能想到的最简单的方法是让你的控制器派生自一个覆盖 View 方法的自定义基类:
public class MyControllerBase : Controller {
public override ViewResult View(string viewName, string masterName, object model) {
if(String.IsNullOrEmpty(masterName)) {
masterName = GetDefaultLayout();
}
base.View(viewName, masterName, model);
}
public virtual string GetDefaultLayout() {
return // your default layout here
}
}
在上面的代码中,您可以将 masterName 显式设置为某个硬编码值。或者您的控制器可以覆盖该方法以提供特定于控制器的布局。或者您可以从控制器上的某些属性中读取它,类似于:
masterName = GetType().GetCustomAttributes().
OfType<MyCustomAttribute>().FirstOrDefault().DefaultLayoutPage;
当然,你必须创建你的MyCustomAttribute
.