首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

ASP.NET MVC AOP 面向切面編程實戰:ActionFilterAttribute 實現全域攔截與權限控制

     編輯:Java 相關知識

雖然 AOP (Aspect-Oriented Programming) 概念源自 Java Spring,但在 ASP.NET MVC 中同樣可透過 ActionFilterAttribute 實現橫切關注點的模組化。本文以實戰代碼示範如何建立自訂 Filter、控制執行順序、實現 Controller/Action/全域三層級攔截,並解決多重 Filter 疊加不生效的常見坑點。

核心類別:FilterPublic

using System.Web.Mvc;

public class FilterPublicAttribute : ActionFilterAttribute {
  public string Message { get; set; }

  public override void OnActionExecuting(ActionExecutingContext filterContext) {
    base.OnActionExecuting(filterContext);
    filterContext.HttpContext.Response.Write($"Action執行之前 {Message} <br/>");
  }

  public override void OnActionExecuted(ActionExecutedContext filterContext) {
    base.OnActionExecuted(filterContext);
    filterContext.HttpContext.Response.Write($"Action執行之後 {Message} <br/>");
  }

  public override void OnResultExecuting(ResultExecutingContext filterContext) {
    base.OnResultExecuting(filterContext);
    filterContext.HttpContext.Response.Write($"前往Result之前 {Message} <br/>");
  }

  public override void OnResultExecuted(ResultExecutedContext filterContext) {
    base.OnResultExecuted(filterContext);
    filterContext.HttpContext.Response.Write($"前往Result之後 {Message} <br/>");
  }
}

三層級套用示範

1. Action 級別

[FilterPublic(Message = "Action")]
public ActionResult Index() {
  HttpContext.Response.Write("Action正在執行···<br/>");
  return Content("正在前往Result···<br/>");
}

2. Controller 級別 (需加 AllowMultiple = true)

[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
public class FilterPublicAttribute : ActionFilterAttribute { ... }

[FilterPublic(Message = "Controller")]
public class HomeController : Controller { ... }

3. 全域級別 (Global.asax)

public class MvcApplication : System.Web.HttpApplication {
  protected void Application_Start() {
    AreaRegistration.RegisterAllAreas();
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
  }
}

public class FilterConfig {
  public static void RegisterGlobalFilters(GlobalFilterCollection filters) {
    filters.Add(new HandleErrorAttribute());
    filters.Add(new FilterPublicAttribute { Message = "全域<br/>" });
  }
}

執行順序與輸出驗證

套用三層後,輸出順序嚴格遵循:

Action執行之前全域
Action執行之前Controller
Action執行之前Action
Action正在執行···
Action執行之後Action
Action執行之後Controller
Action執行之後全域
前往Result之前全域
前往Result之前Controller
前往Result之前Action
正在前往Result···
前往Result之後Action
前往Result之後Controller
前往Result之後全域
  • OnActionExecuting:全域 → Controller → Action (由外而內)
  • OnActionExecuted:Action → Controller → 全域 (由內而外)
  • OnResultExecuting/Executed:同理

關鍵坑點:AllowMultiple = true

若不在自訂 Attribute 加上 [AttributeUsage(AttributeTargets.All, AllowMultiple = true)],Controller 層級與全域層級的同類 Filter 會互相覆蓋,導致只有最內層 (Action) 生效。此屬性允許同一目標套用多個相同類型的 Attribute。

實務應用場景

  1. 權限驗證:OnActionExecuting 檢查 Session/Token,失敗 filterContext.Result = new RedirectResult("/Login")。
  2. 日誌記錄:記錄請求參數、執行時間、回應狀態。
  3. 異常處理:繼承 HandleErrorAttribute 或實作 IExceptionFilter。
  4. 輸出快取/壓縮:OnResultExecuting 設定 Response Headers。
  5. 多語系:OnActionExecuting 解析 Accept-Language 設定 Culture。

總結

ASP.NET MVC 的 ActionFilterAttribute 提供了輕量級 AOP 能力,透過四個生命週期方法精確控制攔截點。掌握 三層級套用順序 與 AllowMultiple 疊加機制,即可實現權限、日誌、快取等橫切關注點的乾淨分離,避免 Controller 膨脹與代碼重複。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved