How to set a Razor layout in MVC via an attribute filter?

孤者浪人 提交于 2019-12-18 13:25:12

问题


I'd like to set a default Razor layout via code in either a base controller or an attribute. It was mentioned in the Docs that this is possible, but I can't figure out how it's done.

I know there's the masterPage parameter to the View method available, but I would like all views returned by a controller to have this value set automatically.

And no, I can't use _ViewStart for this since my views are going to be in various places (this is not a normal MVC site configuration).

Thanks


回答1:


I think you could just write an ActionFilter like...

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";
           }
       }
}

I just wrote this code by the seat of my pants with no compiler so it probably won't compile but you probably get the idea. I think IResultFilter is the correct interface you want, it has methods that execute right before the view is rendered. If this is correct, you should be able to modify the MasterName for the view that is about to be rendered on the fly.

This would be the controller code usage.

[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.
   }
}



回答2:


The easiest way I can think of doing this is by having your controllers derive from a custom base class that overrides the View method:

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
    }
}

In the code above you could explicitly set the masterName to some hardcoded value. Or your Controllers could override the method to provide a Controller-specific layout. Or you could read it from some attribute on the Controller, something similiar to:

masterName = GetType().GetCustomAttributes().
             OfType<MyCustomAttribute>().FirstOrDefault().DefaultLayoutPage;

Of course you'd have to create your MyCustomAttribute.



来源:https://stackoverflow.com/questions/4047810/how-to-set-a-razor-layout-in-mvc-via-an-attribute-filter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!