Asp.net mvc 如何通过属性过滤器在MVC中设置Razor布局?
我想通过基本控制器或属性中的代码设置默认Razor布局。文件中提到这是可能的,但我不知道是怎么做到的 我知道View方法中有masterPage参数,但我希望控制器返回的所有视图都自动设置此值 不,我不能使用_ViewStart,因为我的视图将位于不同的位置(这不是一个普通的MVC站点配置)Asp.net mvc 如何通过属性过滤器在MVC中设置Razor布局?,asp.net-mvc,razor,Asp.net Mvc,Razor,我想通过基本控制器或属性中的代码设置默认Razor布局。文件中提到这是可能的,但我不知道是怎么做到的 我知道View方法中有masterPage参数,但我希望控制器返回的所有视图都自动设置此值 不,我不能使用_ViewStart,因为我的视图将位于不同的位置(这不是一个普通的MVC站点配置) 谢谢我能想到的最简单的方法是让控制器派生自覆盖View方法的自定义基类: public class MyControllerBase : Controller { public override V
谢谢我能想到的最简单的方法是让控制器派生自覆盖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;
masterName=GetType().GetCustomAttributes()。
OfType().FirstOrDefault().DefaultLayoutPage;
当然,你必须创建你的
MyCustomAttribute
我想你可以编写一个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是您想要的正确接口,它具有在视图呈现之前执行的方法。如果这是正确的,您应该能够修改即将动态渲染的视图的母版名
这将是控制器代码的用法
[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.
}
}
我喜欢这里的基本控制器的想法,它似乎是最直接的。您知道属性是否有任何方法可以拦截对视图的调用吗?我不确定您的意思,但属性本身不能做任何事情。它们携带的信息(或者可能是行为)必须由具有上下文的东西(比如ControllerActionInvoker)调用。“intercept”到底是什么意思?如果我构建了一个在视图执行之前执行的操作过滤器属性,我可以修改视图并设置布局页面。我只是不确定是否可以这样修改ActionResult,尽管我怀疑是这样。操作筛选器甚至在创建视图之前就执行了,因此您无法在任何地方设置布局。实际上,您不需要直接从
IResultFilter
继承,因为ActionFilterAttribute
已经这样做了:公共抽象类ActionFilterAttribute:FilterAttribute,IActionFilter,IResultFilter
。