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

ASP.NET MVC 請求處理管線:從 IHttpHandler 到 View 輸出的完整流程圖解

     編輯:ASP.NET 基礎

核心類別繼承鏈

MvcHandler : IHttpHandler
    ↓ ProcessRequest(HttpContext)
Controller : ControllerBase : IController
    ↓ Execute(RequestContext)
ControllerActionInvoker : IActionInvoker
    ↓ InvokeAction → FindAction → InvokeActionMethodWithFilters → InvokeActionResultWithFilters
ViewResultBase : ActionResult
    ↓ ExecuteResult → FindView → ViewEngine → View.Render

關鍵步驟深度解析

1. MvcHandler 進入點

// MvcHandler.cs
protected internal virtual void ProcessRequest(HttpContextBase httpContext)
{
    IController controller;
    IControllerFactory factory;
    ProcessRequestInit(httpContext, out controller, out factory); // 解析路由、建立 ControllerFactory
    try
    {
        controller.Execute(RequestContext); // 執行 Controller
    }
    finally
    {
        factory.ReleaseController(controller); // 釋放 Controller
    }
}

2. Controller 執行核心

// Controller.cs
protected override void ExecuteCore()
{
    PossiblyLoadTempData(); // 讀取 TempData
    try
    {
        string actionName = RouteData.GetRequiredString("action");
        if (!ActionInvoker.InvokeAction(ControllerContext, actionName))
            HandleUnknownAction(actionName); // 404 或預設行為
    }
    finally
    {
        PossiblySaveTempData(); // 寫回 TempData
    }
}

3. ActionInvoker 尋找與執行 Action

// ControllerActionInvoker.cs
public virtual bool InvokeAction(ControllerContext controllerContext, string actionName)
{
    var controllerDescriptor = GetControllerDescriptor(controllerContext);
    var actionDescriptor = FindAction(controllerContext, controllerDescriptor, actionName); // 反射/快取尋找 MethodInfo
    if (actionDescriptor == null) return false;

    var filters = GetFilters(controllerContext, actionDescriptor); // Authorization/Action/Result/Exception Filters

    // 1. Authorization Filters
    var authContext = InvokeAuthorizationFilters(controllerContext, filters.AuthorizationFilters, actionDescriptor);
    if (authContext.Result != null) { InvokeActionResult(controllerContext, authContext.Result); return true; }

    // 2. Model Binding & Validation
    if (controllerContext.Controller.ValidateRequest) ValidateRequest(controllerContext);
    var parameters = GetParameterValues(controllerContext, actionDescriptor); // DefaultModelBinder

    // 3. Action Filters + Action Method
    var actionExecutedContext = InvokeActionMethodWithFilters(controllerContext, filters.ActionFilters, actionDescriptor, parameters);

    // 4. Result Filters + ActionResult.ExecuteResult
    InvokeActionResultWithFilters(controllerContext, filters.ResultFilters, actionExecutedContext.Result);

    return true;
}

4. ViewResult 渲染輸出

// ViewResultBase.cs
public override void ExecuteResult(ControllerContext context)
{
    if (string.IsNullOrEmpty(ViewName))
        ViewName = context.RouteData.GetRequiredString("action");

    ViewEngineResult result = View ?? FindView(context); // RazorViewEngine / WebFormViewEngine
    View = result.View;

    using (var writer = context.HttpContext.Response.Output)
    {
        var viewContext = new ViewContext(context, View, ViewData, TempData, writer);
        View.Render(viewContext, writer); // 呼叫 Razor 編譯產生的 Execute() 寫入 HTML
    }

    if (result != null) result.ViewEngine.ReleaseView(context, View);
}

生命週期關鍵點對照表

階段核心類別/方法可擴充點
路由解析UrlRoutingModule → MvcHandler自訂 RouteBase、IRouteConstraint
Controller 建立DefaultControllerFactory → GetControllerInstanceIControllerFactory、DI 容器整合
Action 選擇ControllerActionInvoker → FindActionActionMethodSelectorAttribute、ActionNameSelectorAttribute
模型繫結DefaultModelBinder → BindModelIModelBinder、ModelBinderProvider
過濾器管線Authorization → Action → Result → ExceptionFilterAttribute、IFilterProvider
View 解析ViewEngineCollection → FindViewIViewEngine、VirtualPathProvider
View 渲染RazorView → Render → Execute()@helpers、HtmlHelper 擴充、TagHelper

ASP.NET Core 差異重點

  • 無 `HttpHandler`/`HttpModule`,改用 **Middleware Pipeline** (`UseRouting` → `UseEndpoints`)。
  • `Controller` 不再繼承 `ControllerBase` (System.Web.Mvc),改為 `ControllerBase` (Microsoft.AspNetCore.Mvc)。
  • `ActionInvoker` 內建於 `ControllerActionInvoker`,但可被 `IActionInvokerFactory` 替換。
  • View Engine 預設僅 **Razor**,WebForms View Engine 已移除。
  • 依賴注入 (DI) 為核心,所有服務 (Controller、Filter、ModelBinder、ViewEngine) 均從容器解析。

小結

理解 MVC 管線從 `IHttpHandler` 進入、經由 `Controller`、`ActionInvoker`、Filter 管線、Model Binding、View Engine 到最終 `View.Render` 輸出,有助於:

  1. 撰寫自訂 Filter、Model Binder、View Engine。
  2. 除錯 404/500 發生在哪個階段。
  3. 遷移至 ASP.NET Core 時對應概念 (Middleware ↔ HttpModule, Endpoint Routing ↔ MvcHandler)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved