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

ASP.NET MVC 案例教程第六篇:攔截器實作日誌與異常處理、AOP 解耦橫切關注點

     編輯:關於ASP.NET

問題:Action 混雜日誌與 try-catch,違反單一職責

發布公告功能需求:執行前/後記錄日誌、異常時導向錯誤頁。直接在 Action 寫導致:

  • 程式碼重複(每個 Action 都要寫)。
  • 職責汙染:Controller 應只負責表示邏輯。

AOP 隱喻:廚師只負責炒菜,切菜/上菜/處理變質食材交給攔截器

  • 業務組件 = 廚師:核心邏輯(炒菜)。
  • 前置攔截器 = 切菜工:Action 執行前準備(記錄開始日誌)。
  • 後置攔截器 = 服務生:Action 執行後收尾(記錄結束日誌、回傳結果)。
  • 異常攔截器 = 處理變質食材者:Action 拋出例外時介入(導向錯誤頁、記錄異常)。

優勢:職責單一、攔截器可復用(多個 Action 共用一組日誌/異常處理邏輯)。

ASP.NET MVC 內建攔截機制:IActionFilter + ActionFilterAttribute

public interface IActionFilter {
    void OnActionExecuting(ActionExecutingContext filterContext); // 前置
    void OnActionExecuted(ActionExecutedContext filterContext);   // 後置
    void OnResultExecuting(ResultExecutingContext filterContext); // 結果前
    void OnResultExecuted(ResultExecutedContext filterContext);   // 結果後
}

兩種實作方式:

  1. Attribute 方式:繼承 ActionFilterAttribute,重寫虛擬方法,標註於 Controller/Action。
  2. Controller 基類方式:Controller 實作 IActionFilter,重寫虛擬方法,影響該 Controller 所有 Action。

實作範例:日誌攔截器

public class LogAttribute : ActionFilterAttribute {
    public override void OnActionExecuting(ActionExecutingContext filterContext) {
        var action = filterContext.ActionDescriptor.ActionName;
        var controller = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
        Log.Info($"[START] {controller}.{action} - Params: {Json.Encode(filterContext.ActionParameters)}");
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext) {
        var action = filterContext.ActionDescriptor.ActionName;
        var controller = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
        if (filterContext.Exception != null)
            Log.Error($"[ERROR] {controller}.{action}", filterContext.Exception);
        else
            Log.Info($"[END] {controller}.{action} - Result: {filterContext.Result.GetType().Name}");
    }
}

實作範例:異常處理攔截器

public class HandleErrorAttribute : ActionFilterAttribute {
    public override void OnActionExecuted(ActionExecutedContext filterContext) {
        if (filterContext.Exception != null && !filterContext.ExceptionHandled) {
            // 記錄異常
            Log.Fatal("Unhandled exception", filterContext.Exception);
            // 導向錯誤視圖
            filterContext.Result = new ViewResult { ViewName = "Error" };
            filterContext.ExceptionHandled = true; // 標記已處理
            // 清除回應內容,避免洩露堆疊追蹤
            filterContext.HttpContext.Response.Clear();
            filterContext.HttpContext.Response.StatusCode = 500;
        }
    }
}

套用方式

[Log]
[HandleError]
public class AnnounceController : Controller {
    public ActionResult DoRelease(...) { ... } // 自動擁有日誌與異常處理
}

或註冊為全域攔截器:GlobalFilters.Filters.Add(new LogAttribute());(MVC 3+)。

總結

攔截器將「日誌、異常處理、效能監控、授權檢查、快取」等橫切關注點從 Action 抽離,實現 AOP,是 MVC 專案架構乾淨、可維護的關鍵基礎設施。

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