很多境況下,我們需要設置自己模塊的layout,即它的布局頁面,在MVC2中叫它模板頁面,你可以在return view方法時設置它,當然,這不是一種好方法,因為我不想每個action都去設置一次,因為我們的controller一般指一個模塊,而一個模塊下的action,它們的layout基本是相同的,所以,有沒有一種方法,在controller級別來實現這個呢,呵呵,當然有,那就是attribute特性,我們在MVC環境下,有一個ActionFilterAttribute,這個想畢大家都聽說過,它記錄了頁面在渲染前與渲染后的狀態,這個特性(或者叫它過濾器)的代碼如下:
// 摘要: // Represents the base class for filter attributes. [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)] public abstract class ActionFilterAttribute : FilterAttribute, IActionFilter, IResultFilter { // 摘要: // Initializes a new instance of the System.Web.Mvc.ActionFilterAttribute class. protected ActionFilterAttribute(); // 摘要: // Called by the ASP.NET MVC framework after the action method executes. // // 參數: // filterContext: // The filter context. public virtual void OnActionExecuted(ActionExecutedContext filterContext); // // 摘要: // Called by the ASP.NET MVC framework before the action method executes. // // 參數: // filterContext: // The filter context. public virtual void OnActionExecuting(ActionExecutingContext filterContext); // // 摘要: // Called by the ASP.NET MVC framework after the action result executes. // // 參數: // filterContext: // The filter context. public virtual void OnResultExecuted(ResultExecutedContext filterContext); // // 摘要: // Called by the ASP.NET MVC framework before the action result executes. // // 參數: // filterContext: // The filter context. public virtual void OnResultExecuting(ResultExecutingContext filterContext); }
OnActionExecuted,OnActionExecuting,OnResultExecuted和OnResultExecuting它們記錄一個action從加載到頁面最終顯示在瀏覽器上的全過程,這個東西我們一般用在頁面權限驗證,layout頁面控制上,它們的執行次序是:
OnActionExecuting action執行前
OnActionExecuted action執行后
OnResultExecuting 頁面渲染前
顯示頁面的內容
OnResultExecuted 頁面渲染結果
如圖所示
我們通過ActionFilterAttribute的特性,寫個派生類,然后去覆寫它的OnActionExecuted方法,將layout頁面修改(注意是修改,因為在action執行之后layout已經是默認的布局頁了)
代碼如下:
/// <summary> /// 自定義模板頁面 /// </summary> public class LayoutAttribute : ActionFilterAttribute { private readonly string _masterName; public LayoutAttribute(string masterName) { _masterName = masterName; } /// <summary> /// 頁面渲染結束后執行 /// </summary> /// <param name="filterContext"></param> public override void OnActionExecuted(ActionExecutedContext filterContext) { base.OnActionExecuted(filterContext); var result = filterContext.Result as ViewResult; if (result != null) { result.MasterName = _masterName; } } }
最后把它應用到controller或者action上,使用很簡單