`MvcHandler` 是 MVC 管線的真正起點,實作 `IHttpHandler`,在 `ProcessRequest` 中完成控制器建立與執行。本文逐行解析原始碼,揭示路由對應、ControllerFactory 建立、Controller 執行全流程。
protected internal virtual void ProcessRequest(HttpContextBase httpContext)
{
AddVersionHeader(httpContext);
string controllerName = RequestContext.RouteData.GetRequiredString("controller");
IControllerFactory factory = ControllerBuilder.GetControllerFactory();
IController controller = factory.CreateController(RequestContext, controllerName);
if (controller == null)
throw new InvalidOperationException(...);
try
{
controller.Execute(RequestContext);
}
finally
{
factory.ReleaseController(controller);
}
}
private void AddVersionHeader(HttpContextBase httpContext)
{
httpContext.Response.AppendHeader("X-AspNetMvc-Version", "1.0");
}
回應標頭標示 MVC 版本,便於診斷與相容性檢測。
string controllerName = RequestContext.RouteData.GetRequiredString("controller");
路由表 (`RouteCollection`) 在 `UrlRoutingModule.PostResolveRequestCache` 階段已解析並填入 `RouteData.Values["controller"]`。
public ControllerBuilder()
{
SetControllerFactory(new DefaultControllerFactory { ControllerBuilder = this });
}
| 擴充點 | 用途 | 實作方式 |
|---|---|---|
| IControllerFactory | 完全掌控控制器建立/釋放 | 實作介面,`ControllerBuilder.Current.SetControllerFactory()` |
| DefaultControllerFactory | 調整控制器類型搜尋邏輯 | 繼承覆寫 `GetControllerType`、`GetControllerInstance` |
| ControllerBuilder | 設定預設命名空間、快取控制器類型 | `ControllerBuilder.Current.DefaultNamespaces.Add()` |
HttpRequest
↓
UrlRoutingModule → RouteData
↓
MvcHandler.ProcessRequest
↓
ControllerBuilder → IControllerFactory
↓
CreateController(controllerName)
↓
Controller.Execute(RequestContext)
↓
ExecuteCore → TempData.Load → ActionInvoker.InvokeAction → TempData.Save
↓
ReleaseController
↓
HttpResponse
掌握 `MvcHandler` 入口機制,能深入理解 MVC 請求處理全貌,並能在極早期攔截請求 (如自訂 `IHttpModule` 配合 `PreRequestHandlerExecute`),實現多租戶路由、動態控制器載入等進階架構。