Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 如何通过属性过滤器在MVC中设置Razor布局?_Asp.net Mvc_Razor - Fatal编程技术网

Asp.net mvc 如何通过属性过滤器在MVC中设置Razor布局?

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

我想通过基本控制器或属性中的代码设置默认Razor布局。文件中提到这是可能的,但我不知道是怎么做到的

我知道View方法中有masterPage参数,但我希望控制器返回的所有视图都自动设置此值

不,我不能使用_ViewStart,因为我的视图将位于不同的位置(这不是一个普通的MVC站点配置)


谢谢

我能想到的最简单的方法是让控制器派生自覆盖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