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

ASP.NET MVC 1.0 深度剖析 (3):ActionInvoker.InvokeAction 完整流程追蹤

     編輯:關於ASP.NET

`Controller.ExecuteCore()` 呼叫 `ActionInvoker.InvokeAction()` 進入 Action 執行管線。本文逐行解析 `InvokeAction` 原始碼,揭示授權過濾器、模型綁定、Action 執行、結果執行、異常處理完整生命週期。

InvokeAction 核心流程圖

  1. 參數驗證:`controllerContext`、`actionName` 不可為 null/空。
  2. 尋找 ActionDescriptor:`FindAction()` 依路由值尋找對應方法。
  3. 取得過濾器:`GetFilters()` 取得 Authorization、Action、Result、Exception 四類過濾器。
  4. 授權階段:`InvokeAuthorizationFilters()`,若 `authContext.Result != null` 直接執行結果(如導向登入頁)。
  5. 驗證請求:`ValidateRequest()` 防 XSRF/惡意輸入。
  6. 模型綁定:`GetParameterValues()` 為 Action 參數賦值(見第 4 篇 ModelBinder)。
  7. Action 執行 (含 Action Filters):`InvokeActionMethodWithFilters()` 執行 Action 方法,前後包裹 `OnActionExecuting/Executed`。
  8. 結果執行 (含 Result Filters):`InvokeActionResultWithFilters()` 執行 `ActionResult.ExecuteResult()`,前後包裹 `OnResultExecuting/Executed`。
  9. 異常處理:捕獲 `ThreadAbortException` (Response.Redirect) 直接重拋;其他例外進入 `InvokeExceptionFilters()`,若未處理則重拋,否則執行錯誤結果。

關鍵原始碼節錄

public virtual bool InvokeAction(ControllerContext controllerContext, string actionName)
{
    // ... 參數檢查 ...
    ActionDescriptor actionDescriptor = FindAction(controllerContext, controllerDescriptor, actionName);
    if (actionDescriptor != null)
    {
        FilterInfo filterInfo = GetFilters(controllerContext, actionDescriptor);
        try
        {
            AuthorizationContext authContext = InvokeAuthorizationFilters(controllerContext, filterInfo.AuthorizationFilters, actionDescriptor);
            if (authContext.Result != null)
            {
                InvokeActionResult(controllerContext, authContext.Result);
            }
            else
            {
                if (controllerContext.Controller.ValidateRequest)
                    ValidateRequest(controllerContext.HttpContext.Request);

                IDictionary<string, object> parameters = GetParameterValues(controllerContext, actionDescriptor);
                ActionExecutedContext postActionContext = InvokeActionMethodWithFilters(controllerContext, filterInfo.ActionFilters, actionDescriptor, parameters);
                InvokeActionResultWithFilters(controllerContext, filterInfo.ResultFilters, postActionContext.Result);
            }
        }
        catch (ThreadAbortException) { throw; }
        catch (Exception ex)
        {
            ExceptionContext exceptionContext = InvokeExceptionFilters(controllerContext, filterInfo.ExceptionFilters, ex);
            if (!exceptionContext.ExceptionHandled) throw;
            InvokeActionResult(controllerContext, exceptionContext.Result);
        }
        return true;
    }
    return false; // 找不到 Action
}

Filter 執行順序總結

Authorization Filters (OnAuthorization)
    ↓
Action Filters (OnActionExecuting)
    ↓
Action Method
    ↓
Action Filters (OnActionExecuted)
    ↓
Result Filters (OnResultExecuting)
    ↓
ActionResult.ExecuteResult()
    ↓
Result Filters (OnResultExecuted)

異常發生時跳轉至 Exception Filters (`OnException`),若 `ExceptionHandled=true` 則執行其指定結果,否則冒泡。

實務啟示

  • 授權失敗應回傳 `HttpUnauthorizedResult` 或 `RedirectToRouteResult`,而非拋例外。
  • Action Filter 可在 `OnActionExecuting` 修改參數、取消執行 (設 `filterContext.Result`)。
  • Result Filter 可包裝/轉換 `ActionResult` (如統一加入 JSONP 回呼)。
  • 全域錯誤處理建議註冊 `HandleErrorAttribute` 或自訂 `Exception Filter` 記錄日誌、回傳友善錯誤頁。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved