91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

進入MVC處理通道

發布時間:2020-07-26 06:11:18 來源:網絡 閱讀:288 作者:xmgdc 欄目:網絡安全

首先來看一下經典的Asp.net處理管道的生命周期。

 進入MVC處理通道

我們知道一個ASP.NET應用程序可以有多個HttpModule,但是只能有一個HttpHandler,并且通過這個HttpHandler的BeginProce***equest(或Proce***equest)來處理并返回請求,查看聲明處理管道周期可知在MapHttpHandler這個周期將會根據請求的URL來查詢對應的HttpHandler,那么它是如何查找的呢。

查找系統web.config中的httpModules配置節,在倒數第二行發現一個name為UrlRoutingModule-4.0的IHttpModule配置,這是查找HttpHandler的關鍵之處。下面分析一下UrlRoutingModule的代碼:

進入MVC處理通道

    protected virtual void Init(HttpApplication application) {        if (application.Context.Items[_contextKey] != null) {            return;

        }

        application.Context.Items[_contextKey] = _contextKey;

        application.PostResolveRequestCache += OnApplicationPostResolveRequestCache;

    }    private void OnApplicationPostResolveRequestCache(object sender, EventArgs e) {

        HttpApplication app = (HttpApplication)sender;

        HttpContextBase context = new HttpContextWrapper(app.Context);

        PostResolveRequestCache(context);

    }    public virtual void PostResolveRequestCache(HttpContextBase context) {

        RouteData routeData = RouteCollection.GetRouteData(context);

……

        IRouteHandler routeHandler = routeData.RouteHandler;

        ……

        RequestContext requestContext = new RequestContext(context, routeData);

        context.Request.RequestContext = requestContext;

        IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext);

        ……

        context.RemapHandler(httpHandler);

}

進入MVC處理通道

可以看到UrlRoutingModule設置了一個PostResolveRequestCache事件處理方法,該方法從RouteCollection通過匹配找到請求對應的路由數據RouteData(包含如Mvc中的Controller名、Action名等),然后從RouteData的屬性RouteHandler獲取一個IRouteHandler的實例,再從IRouteHandler實例里獲取對應的IHttpHandler實例,最后調用HttpContext的RemapHandler方法重新為HttpContext設置RemapHandlerInstance。

根據前面asp.net初始化流程分析2我們知道在獲取Httphandler時經典模式和集成模式使用了不同的IExecutionStep,經典模式用的是MapHandlerExecutionStep集成模式用的是MaterializeHandlerExecutionStep,查看二者的執行方法Execute。

先看MaterializeHandlerExecutionStep。

進入MVC處理通道

    void IExecutionStep.Execute() {

        HttpContext context = _application.Context;

        HttpRequest request = context.Request;

        IHttpHandler handler = null;        string configType = null;

        ……        if (context.RemapHandlerInstance != null){

            wr.SetScriptMapForRemapHandler();

            context.Handler = context.RemapHandlerInstance;

        }

……

}

進入MVC處理通道

可以看到MaterializeHandlerExecutionStep中如果UrlRoutingModule模塊中在HttpContext設置了RemapHandlerInstance,則直接用RemapHandlerInstance設置HttpContext的Handler。

再看MapHandlerExecutionStep。

進入MVC處理通道

    void IExecutionStep.Execute() {

        HttpContext context = _application.Context;

        HttpRequest request = context.Request;

        ……

        context.Handler = _application.MapHttpHandler(context, request.RequestType, request.FilePathObject, request.PhysicalPathInternal, false /*useAppConfig*/);

        ……

}

進入MVC處理通道

在MapHandlerExecutionStep中會調用HttpApplication的MapHttpHandler方法來設置HttpContext的Handler。下面查看MapHttpHandler代碼:

進入MVC處理通道

    internal IHttpHandler MapHttpHandler(HttpContext context, String requestType, VirtualPath path, String pathTranslated, bool useAppConfig) {

        IHttpHandler handler = (context.ServerExecuteDepth == 0) ? context.RemapHandlerInstance : null;        using (new ApplicationImpersonationContext()) {            if (handler != null){                return handler;

        }
        ……
    }

進入MVC處理通道

從第一行代碼就可以看到如果HttpContext的RemapHandlerInstance不為空則直接返回HttpContext的RemapHandlerInstance(context.ServerExecuteDepth是指頁面是否使用了HttpServerUtility.Execute進行頁面內跳轉)。這樣也就同樣使用了UrlRoutingModule模塊中在HttpContext設置的RemapHandlerInstance,至于HttpContext沒有設置的RemapHandlerInstance的情況下如何根據默認的擴展名匹配查找HttpHandler就不在此討論了。

通過上面的分析我們可以設想通過在UrlRoutingModule中的靜態RouteCollection屬性中注冊RouteData而且設置該RouteData的IRouteHandler(一個接口,只有一個方法GetHttpHandler用來獲取HttpHandler)來實現路由與HttpHandler的對應。下面來分析一下MvcHandler是如何通過路由注冊的,首先來看RouteCollection的實現

進入MVC處理通道

    public RouteCollection RouteCollection {        get {            if (_routeCollection == null) {

                _routeCollection = RouteTable.Routes;

            }            return _routeCollection;

        }        set {

            routeCollection = value;

        }

}

進入MVC處理通道

可以看到RouteCollection其實是包裝了RouteTable中的靜態Routes,如果有Mvc項目經驗的話應該很眼熟了,一般的Mvc程序在Global.asax中一般都有這么一段用來注冊路由:

進入MVC處理通道

    protected void Application_Start()
    {
        ……
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        ……
    }    public class RouteConfig
    {        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
        }
    }

進入MVC處理通道

而我們定義的路由設置MvcHandler的奧妙正在MapRoute方法里,這是一個擴展方法,定義在System.Web.Mvc.RouteCollectionExtensions里:

進入MVC處理通道

public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces)

{

    ……

        Route route = new Route(url, new MvcRouteHandler())

        {

            Defaults = CreateRouteValueDictionaryUncached(defaults),

            Constraints = CreateRouteValueDictionaryUncached(constraints),

            DataTokens = new RouteValueDictionary()

        };

        ……

        routes.Add(name, route);        return route;

}

進入MVC處理通道

可以看到MapRoute注冊路由是綁定了一個MvcRouteHandler作為IRouteHandler,下面看MvcRouteHandler是如何實現的:

    protected virtual IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        requestContext.HttpContext.SetSessionStateBehavior(GetSessionStateBehavior(requestContext));        return new MvcHandler(requestContext);
    }

在這里終于看到了創建MvcHandler的代碼。

至此,我們應該有一個清晰的認識了,我們通過全局靜態屬性集合(RouteTable.Routes)去添加各種各樣的Route(但應該在HttpModule初始化周期之前,一般是利用HttpApplication創建的周期在Application_Start方法中添加了我們所需要的Route規則),當然在添加路由的時候帶上了MvcHandler這個重要的HttpHandler。然后通過UrlRoutingModule在PostResolveRequestCache周期通過查找注冊的Route獲取請求的RouteData以及其屬性IRouteHandler實例(至于路由是如何匹配的還要等后續的篇章繼續講),然后通過IRouteHandler實例可以通過GetHttpHandler獲取IHttpHandler并將其設置到HttpContext的RemapHandlerInstance屬性。最終在MapHttpHandler周期通過獲取HttpContext的RemapHandlerInstance實現了不同的HttpHandler來接管匹配不同路由的URL。


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

mvc
AI

贺州市| 永清县| 东安县| 新安县| 临桂县| 嘉禾县| 德格县| 赣榆县| 徐水县| 思南县| 五大连池市| 台东县| 汕头市| 潜山县| 灵武市| 遂昌县| 德阳市| 高邑县| 鄱阳县| 天等县| 兴宁市| 彭水| 扬州市| 龙山县| 琼海市| 武胜县| 会理县| 潞西市| 新邵县| 宝丰县| 平阳县| 海晏县| 衡阳市| 巢湖市| 车险| 应用必备| 怀柔区| 泗洪县| 正安县| 蚌埠市| 临洮县|