Controller的啟用與URL路由
Controller的啟用與URL路由
ASP.NET路由系統是HTTP請求抵達服務端的第一道屏障,它根據註冊的路由規則對攔截的請求進行匹配並解析包含目標Controller和Action名稱的路由資訊。而當前ControllerBuilder具有用於啟用Controller物件的ControllerFactory,現在看看兩者是如何結合起來的。
透過第2章“URL路由”的介紹我們知道,ASP.NET路由系統的核心是一個叫做UrlRoutingModule的HttpModule,路由的實現是它透過註冊代表HttpApplication的PostResolveRequestCache事件對HttpHandler的動態對映來實現的。具體來說,它透過以RouteTable的靜態屬性Routes代表的全域性路由表對請求進行匹配並得到一個RouteData物件。RouteData具有一個實現了介面IRouteHandler的屬性RouteHandler,透過該屬性的GetHttpHandler方法可以得到最終被對映到當前請求的HttpHandler物件。
對於ASP.NET MVC應用來說,RouteData的RouteHandler屬性型別為MvcRouteHandler,實現在MvcRouteHandler中的HttpHandler提供機制基本上(不是完全等同)可以透過如下的程式碼來體現。MvcRouteHandler維護著一個ControllerFactory物件,該物件可以在建構函式中指定,如果沒有顯示指定則直接透過呼叫當前ControllerBuilder的GetControllerFactory方法獲取。
public class MvcRouteHandler : IRouteHandler
{
private IControllerFactory _controllerFactory;
public MvcRouteHandler(): this(ControllerBuilder.Current
.GetControllerFactory())
{ }
public MvcRouteHandler(IControllerFactory controllerFactory)
{
_controllerFactory = controllerFactory;
}
IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext)
{
string controllerName = (string)requestContext.RouteData
.GetRequiredString("controller");
SessionStateBehavior. sessionStateBehavior. = _controllerFactory
.GetControllerSessionBehavior(requestContext, controllerName);
requestContext.HttpContext.SetSessionStateBehavior(sessionStateBehavior);
return new MvcHandler(requestContext);
}
}
在用於提供HttpHandler的GetHttpHandler方法中,除了返回一個實現了IHttpHandler介面的MvcHandler物件之外,還需要對當前HTTP上下文的會話狀態行為模式進行設定。具體的實現是:先透過包含在RequestContext的RouteData物件得到Controller的名稱,該名稱連同RequestContext物件一起傳入ControllerFactory的GetControllerSessionBehavior方法得到一個型別為SessionStateBehavior的列舉。最後透過RequestContext得到當前HTTP上下文(實際上是一個HttpContextWrapper物件),並呼叫其SetSessionStateBehavior方法對會話狀態行為進行設定。
透過第2章“URL路由”的介紹我們知道,RouteData中的RouteHandler屬性最初來源於對應的路由物件,而當我們呼叫RouteCollection的擴充套件方法MapRoute方法時註冊的Route物件對應的RouteHandler是一個MvcRouteHandler物件。由於在建立MvcRouteHandler物件時並沒有顯式指定ControllerFactory,所以透過當前ControllerBuilder的GetControllerFactory方法得到的ControllerFactory預設被使用。
透過當前ControllerBuilder的GetControllerFactory方法得到的ControllerFactory僅僅用於獲取會話狀態行為模式,而MvcHandler真正將它用於建立Controller。如下的程式碼片段基本上體現了MvcHandler的定義,它對請求處理的邏輯定義在BeginProcessRequest方法中。
public class MvcHandler : IHttpAsyncHandler, IHttpHandler, IRequiresSessionState
{
//其他成員
public RequestContext RequestContext { get; private set; }
public bool IsReusable
{
get { return false; }
}
public MvcHandler(RequestContext requestContext)
{
this.RequestContext = requestContext;
}
IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb,
object extraData)
{
IControllerFactory controllerFactory =
ControllerBuilder.Current.GetControllerFactory();
string controllerName =
this.RequestContext.RouteData.GetRequiredString("controller");
IController controller = controllerFactory
.CreateController(this.RequestContext, controllerName);
if (controller is IAsyncController)
{
try
{
//呼叫BeginExecute/EndExecute方法以非同步的方式執行Controller
}
finally
{
controllerFactory.ReleaseController(controller);
}
}
else
{
try
{
//呼叫Execute方法以非同步的方式執行Controller
}
finally
{
controllerFactory.ReleaseController(controller);
}
}
}
}
由於MvcHandler同時實現了IHttpHandler和IHttpAsyncHandler介面,所以它總是以非同步的方式被執行(呼叫BeginProcessRequest/EndProcessRequest方法)。BeginProcessRequest方法透過RequestContext物件得到目標Controller的名稱,然後利用當前ControllerBuilder建立的ControllerFactory啟用Controller物件。如果Controller型別實現了IAsyncController介面,則以非同步的方式執行Controller,否則採用同步執行方式。在被啟用Controller物件被執行之後,MvcHandler會呼叫ControllerFactory的ReleaseController對其進行釋放清理工作。
本文節選自《ASP.NET MVC 4 框架揭秘》
蔣金楠 著
電子工業出版社出版
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/13164110/viewspace-754780/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Go 1.22中路由 URL 路由引數Go路由
- 動態路由(URL引數)路由
- RESTful在路由url有名義的寫法REST路由
- thinkphp6 強制路由不生效問題 以及Url路由去掉應用目錄PHP路由
- MVC中獲取當前URL、controller、actionMVCController
- Netty URL路由方案探討Netty路由
- Django基礎之二(URL路由)Django路由
- POST URL 地址資料開啟URL地址
- Laravel重寫資源路由自定義URLLaravel路由
- react中路由傳參和url傳參React路由
- URL與URL編碼詳解
- express框架路由配置及controller自動載入Express框架路由Controller
- CI框架中的site_url()與base_url()框架
- URL編碼:原理、應用與安全性
- 前端路由與後端路由的思考前端路由後端
- OSPF路由 與 ISIS路由 與路由學習對比路由
- Yii2 URL路徑優化之去除controller標識優化Controller
- 通過 URL 開啟 Activity
- Angular專案下一個路由如何接收到上一個路由url中的引數idAngular路由
- Nuxt.js 路由管理:useRouter 方法與路由中介軟體應用UXJS路由
- ASP.NET MVC 設定 Route 使 URL 中不顯示 controllerASP.NETMVCController
- SpringMVC使用註解完成 URL 和 Controller & 方法之間的對映細節SpringMVCController
- Asp.Net MVC2.0 Url 路由入門(轉)ASP.NETMVC路由
- ASP.NET MVC Controller啟用系統詳解:預設實現ASP.NETMVCController
- SAP UI5 應用開發教程之一百零六 - 如何提高 SAP UI5 應用路由 url 的可讀性UI路由
- 淺析路由策略與策略路由路由
- 瀏覽器標籤管理應用:URL Manager Pro for Mac v6.4.1啟用版瀏覽器Mac
- URL Manager Pro for Mac(瀏覽器標籤管理應用) v5.6啟用版Mac瀏覽器
- Flask 應用中的 URL 處理Flask
- hyperf 路由註解 方法小駝峰 url 蛇形實現路由
- 【基礎進階】URL詳解與URL編碼
- angular2中讓路由連結保持啟用狀態Angular路由
- ASP.NET Core Controller與IOC的羈絆ASP.NETController
- kubernetes實踐之四十八:Service Controller與Endpoint ControllerController
- FastAPI 的路由介紹與使用ASTAPI路由
- history與hash路由的區別路由
- URL、URI與URN 區別
- 路由策略和策略路由配置與管理-1路由