<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Asp.Net MVC3 簡單入門第一季(四)詳解Request Processing Pipeline

      引子

            很久沒更新了,今天寫點關于Asp.Net MVC的PipeLine。首先我們確認一點,Asp.Net WebFrom和Asp.Net MVC是在.Net平臺下的兩種web開發方式。其實他們都是基于Asp.Net Core的不同表現而已。看下面一張圖,我們就能理解了WebForm和Asp.Net MVC的一個關系了。

      那好我們了解了Asp.Net平臺下的兩種開發方式,相信大家對于WebForm的Pipeline都非常熟悉了,當然這也是你熟悉Asp.Net開發的必經之路。而看了很多關于Asp.Net MVC的資料很少有把整個Pipeline講的非常清楚的。我暫時將自己淺陋的整理和理解總結如下,歡迎高手拍磚!

      第一階段:客戶端請求

      客戶端通過瀏覽器、其他軟件、自己編寫WebClinet、模擬HttpRequest等方法來請求一個URL。當然在Asp.Net WebFrom下,所有的請求都是歸結到Handler上,普通的Aspx、Ascx等都是繼承自IHttpHandler接口的一些實例,所以我總結出來:WebFrom下所有的請求都是請求的Handler【不考慮Url重寫】。而做Asp.Net MVC的項目呢,所有的請求是都歸結到Action上,Url應該是直接請求Action。

      客戶端發出請求后,此請求就會通過網絡發出,可能經過多個路由、還可能經過域名解析等等....

      可能請求的是一個集群IP或者單個服務器,但是最終肯定只能由一臺Web服務器的來處理此次請求。

      第二階段:IIS Web服務器

              當一個請求到達IIS服務器后,Windows系統的內核模塊 HTTP.SYS就能監聽到此次請求,并將此次請求的URL、IP以及端口等信息解析出來并將此請求交給注冊的應用來處理:也就是IIS的站點。請求此時就到達了IIS,IIS【此處僅代表IIS6.0版本】就會去檢查此次請求的URL的后綴并將相應的請求交給配置的處理后綴相應的isapi。如果是.aspx或者ascx等直接交給默認設置了此處理項的AspNet_isapi.dll來處理,如果我們想處理Asp.Net MVC的請求的話,我們需要在IIS里面設置處理*.*請求交給AspNet_isapi.dll來處理,才能將一個普通的MVC請求的URL:Http://localhost/DemoController/DemoAction交給AspNet_Isapi.dll來處理。

      第三階段:Asp.Net 運行時

      此時請求到AspNet_Isapi.dll后,它負責啟動Asp.Net RunTime【如過啟動了,直接將請求交給RunTime】。Asp.Net 運行時【HttpRuntime】此時會初始化一下HttpContext上下文,并從HttpApplicationFactory去創建一個HttpApplication對象,并將HttpContext賦值給HttpApplication,此后HttpContext的信息就會一直在管道內往下傳遞。

      HttpApplication對象開始初始化WebConfig文件中注冊的IHttpModule,請求帶著請求信息【HttpContext】隨著管道流過多個HttpModule【一般可以做為權限校驗、行為記錄、日志等等,就是在到達Handler之前我們都可以直接處理此次Http請求,甚至可以重寫URL】,當然也會經過我們注冊的一些自定義的IHttpModule,在.Net 4.0的machine  的config文件中默認配置了一個URLRouteModule,這個也就是我們普通的Asp.Net MVC項目中的路由DLL引用【System.Web.Routing】內部的一個實現了IHttpModule接口的實例類。請求最終流向了路由組件。

      第四階段:Routing組件

      如果你用的是MVC 2+ .NET 3.5,則你會在你的web項目中發現UrlRoutingModule就配置在你的Web.Config。.NET 4卻是在.Net的默認配置文件中配置的。

      UrlRoutingModule做了這么幾個工作:首先他會拿著你的請求到路由表中去匹配相應的路由規則。而路由表規則的定義是在HttpApplication初始化的時候由靜態方法執行的,且看一個普通的Asp.Net MVC項目的Global.asax

       public class MvcApplication : System.Web.HttpApplication
      {
      public static void RegisterGlobalFilters(GlobalFilterCollection filters)
      {
      filters.Add(new HandleErrorAttribute());
      }
      public static void RegisterRoutes(RouteCollection routes)//定義路由表規則
      {
      routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
      routes.MapRoute(
      "Default", // 路由名稱
      "{controller}/{action}/{id}", // 帶有參數的 URL
      new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 參數默認值
      );
      }
      protected void Application_Start()
      {
      AreaRegistration.RegisterAllAreas();
      RegisterGlobalFilters(GlobalFilters.Filters);
      RegisterRoutes(RouteTable.Routes);//注冊路由表
      }
      }

      而路由表的規則的注冊是在 Application_Start() 方法內部,那此時請求在URLRouteModule內部到路由表中的所有規則進行匹配,并把匹配的Controller的信息和Action的信息以及RouteData等信息都解析處理,然后將請求進一步交給:實現了IRouteHandler【實現了IHttpHandler接口】 的一個實例,下面是IRouteHandler的源碼:

      namespace System.Web.Routing
      {
      public interface IRouteHandler
      {
      IHttpHandler GetHttpHandler(RequestContext requestContext);
      }
      }

      如果你想自己來實現這個接口然后在Web.Config中配置一下,那么請求就到了你自己的自定義的RouteHandler來執行后續的請求處理操作了。如果你使用的是默認的配置,那么請求會傳遞到MvcRouteHandler,那么請求f附加著HttpContext就會到達Asp.Net MVC的處理中了。

      第五階段:MvcRouteHandler創建Controller

      請求到此,其實跟WebForm都是一致的,而后面才出現了一些不同,此時請求才真正的進入System.Web.Mvc控制的領域內。后面所有的東西我們都可以直接通過源碼來介紹了,而上面的所有的請求處理只能通過反射等方式來看或者學習,而后面的內容,我們可以幸福的直接看源碼了。那就跟我走進它的管道怎么流動的吧...

      接著上面講,請求到了MvcRouteHandler類,而此類的源碼如下:

      namespace System.Web.Mvc
      {
      using System.Web.Routing;
      using System.Web.SessionState;
      public class MvcRouteHandler : IRouteHandler
      {
      private IControllerFactory _controllerFactory;
      public MvcRouteHandler()
      {
      }
      public MvcRouteHandler(IControllerFactory controllerFactory)
      {
      _controllerFactory = controllerFactory;
      }
      protected virtual IHttpHandler GetHttpHandler(RequestContext requestContext)//實現了IRouteHandler的方法,URLRouteModule調用
      {
      requestContext.HttpContext.SetSessionStateBehavior(GetSessionStateBehavior(requestContext));
      return new MvcHandler(requestContext);
      }
      .....
      }

      MvcRouteHandler的GetHttpHandler方法被URLRouteModule調用,而看上面的紅色源碼部分我們看到,它將請求上下文交給了MVCHandler,并返回了MVCHandler。

      而我查看源碼得知:MVCHandler實現了IHttpHandler,此時它的ProcessRequest方法被調用。且看MVCHandler的部分源代碼:

       public class MvcHandler : IHttpAsyncHandler, IHttpHandler, IRequiresSessionState
      {
      protected internal virtual void ProcessRequest(HttpContextBase httpContext)
      {
      SecurityUtil.ProcessInApplicationTrust(() =>
      {
      IController controller;//在ProcessRequestInit方法中:controller = factory.CreateController(RequestContext, controllerName);//初始化
                      IControllerFactory factory;//是由ProcessRequestInit方法中這行代碼初始化的: factory = ControllerBuilder.GetControllerFactory();
                      ProcessRequestInit(httpContext, out controller, out factory);//初始化了ControllerFactory
      try
      {
      controller.Execute(RequestContext);
      }
      finally
      {
      factory.ReleaseController(controller);
      }
      });
      }
      }

      從源碼中我們得知:請求交給MVCHandler后,它首先從ControllerBuilder獲取到當前的實現了IControllerFactory接口的ControllerFactory【也可以自己定義相關的CustomerControllerFactory,然后在Glable中注冊使用】。然后根據上下文中請求的Controller的字符串信息創建出實現了IController接口的控制器。然后調用了上面代碼中紅色部分,也就是controller.Execute(RequestContext);

      那此時請求就交給了controller。

      第六階段:Controller調用Action返回ActionResult

      由于此文過長,而且時間已經到了凌晨。源碼我就不貼了,簡單介紹一下流程,后面再做詳細贅述。

      Controller的Execute方法是在基類ControllerBase中的方法,而此方法又調用ExecuteCore方法,然后此方法內部執行如下代碼:

      string actionName = RouteData.GetRequiredString("action");
      if (!ActionInvoker.InvokeAction(ControllerContext, actionName))
      {
      HandleUnknownAction(actionName);
      }

      首先從RouteData中獲取Action的名字,然后調用ActonInvoker的InvokeAction方法,調用Action執行。Action的返回的ActionResult的ExecuteResult(controllerContext)方法被執行,那此時就出現了分叉。如果直接返回的非ViewResult的話,那就直接協會到Respose流了返回客戶端了,如果是ViewResult的話,那就進入View的領域了。

      第七階段:View視圖加載成Page類,并Render成Html

      此時請求到ViewResult后,ExecuteResult方法被調用,且看此方法的內部實現:

       public override void ExecuteResult(ControllerContext context)
      {
      if (context == null)
      {
      throw new ArgumentNullException("context");
      }
      if (String.IsNullOrEmpty(ViewName))
      {
      ViewName = context.RouteData.GetRequiredString("action");
      }

      ViewEngineResult result = null;

      if (View == null)
      {
      result = FindView(context);//通過視圖引擎獲取到ViewEngineResult ,此時模板頁面【aspx】被加載成了對應的ViewPage類
      View = result.View;
      }

      TextWriter writer = context.HttpContext.Response.Output;
      ViewContext viewContext = new ViewContext(context, View, ViewData, TempData, writer);
      View.Render(viewContext, writer);

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

             內部主要是通過ViewResult的FindView方法通過ViewEngine去加載具體的Aspx頁面或者是cshtml頁面生成對應的page類【針對Aspx】,然后再調用IView接口的Render方法將請求信息+ViewData的信息以等一塊渲染成Html并寫回到客戶端。

      在此階段我們發現IViewEngine內部的實現這是到規定路徑下去加載Aspx頁面生成對應的ViewPage類。

      IView接口的Render方法才是真正的去將Html和數據裝配的到一塊。

      自此請求結束。

      總結:

      客戶端請求→路由器→IIS服務器內核模塊HTTP.SYS→IIS→AspNet_isapi.dll→Asp.Net Runtime→Application→IHttpModule....IHttpModule→MVCRouteModule→MVCRouteHandler→MVCHandler→ControllerFactory

      →Controller→ActionInvoke→Aciton→ActiongResult.ExcuteReuslt()【如果是ViewResult】→IViewEngine FindView→IView Render→Response

      最后附兩張關于此請求管道的兩張圖,以饗讀者。

       

       

      記于 2011年10月12日0:24:42
      轉載請注明出處:博客園Flydragonhttp://www.rzrgm.cn/fly_dragon

       

      初識Asp.Net MVC2.0

      初識Asp.Net MVC2.0【續】

      Asp.Net MVC2.0 Url 路由入門---實例篇

      Asp.Net MVC2.0 Url 路由入門

      Asp.Net MVC3 簡單入門第一季(一)環境準備

      Asp.Net MVC3 簡單入門第一季(二)詳解Asp.Net MVC3項目

      Asp.Net MVC3 簡單入門第一季(三)詳解Controller之FilteAsp.Net MVC3 簡單入門第一季(四)詳解Request Processing Pipeline

       

      posted @ 2011-10-12 00:52  FlyDragon  閱讀(19398)  評論(39)    收藏  舉報
      主站蜘蛛池模板: 久女女热精品视频在线观看| 成人综合人人爽一区二区| 亚洲毛片多多影院| 国产精品VA尤物在线观看| 桂平市| 中文字幕在线日韩| 女人裸体性做爰视频| 日本黄色一区二区三区四区| 国产成人av电影在线观看第一页| 亚洲中文字幕国产精品| 玩弄放荡人妻少妇系列 | 亚洲日韩av无码一区二区三区| 性视频一区| 国产无遮挡真人免费视频| 国产精品久久香蕉免费播放| 国产成人人综合亚洲欧美丁香花| 欧美成人黄在线观看| 97精品人妻系列无码人妻| 国产精品国产三级国产试看| 久久久久久久久久久久中文字幕| 在线a亚洲v天堂网2018| 国产精品自拍午夜福利| 亚洲精品国产字幕久久麻豆| 9191国语精品高清在线| 人人爽人人爽人人片a免费| 欧美激情a∨在线视频播放| 青草成人精品视频在线看| 久久精品国产再热青青青| 97精品伊人久久大香线蕉APP| 日本视频一区二区三区1| 欧美日韩中文字幕久久伊人| 亚洲午夜激情久久加勒比| 中文字幕亚洲国产精品| 国产成人一区二区三区免费| 久久三级国内外久久三级| 国产午夜福利精品久久不卡| 奎屯市| 精品一卡2卡三卡4卡乱码精品视频| 欧美做受视频播放| 亚洲女同精品中文字幕| 亚洲中文久久久精品无码|