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

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

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

      asp.net Mvc學(xué)習(xí)之URL路由

      Asp.Net MVC的請求的執(zhí)行過程粗略的來看大致是這樣的:

       

      1 WebServer 接收來自的客戶端的Request(請求)

      2 Web Application在第一次運行的時候(Application_Start())根據(jù)其中的設(shè)置代碼會創(chuàng)建一個RouteTable(路由表)實現(xiàn)URL到處理程序之間的映射。

      3 UrlRotingModule模塊解析該請求的URL,并選擇相關(guān)的URL路由。

      4 MvcHandler對象來處理該URL路由,創(chuàng)建要執(zhí)行的控制器(Controller )

      5 執(zhí)行Controller(即調(diào)用指定的執(zhí)行方法)。

      6 返回處理結(jié)果(執(zhí)行View()方法,返回視圖到瀏覽器)。

       

      那么我們首先來深入了解一下URL路由。其實URL路由是ASP.NET 3.5 MVC框架中獨立出來的一個功能,也就是說不僅僅在MVC中,即使是在傳統(tǒng)的WebForm也可以使用它。

       

      ------------------------------------------------------------------------------------------------------------------------------------------

       

      首先,URL路由是如何加入到HttpApplication處理管道中來的?

       

      我們注意到MVC項目的WebConfig中有這么一個配置項

      <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

      那么UrlRoutingModule必然是處理URL路由的一個HttpModule了,將System.Web.Routing進(jìn)行反編譯,并找到UrlRoutingModule這個類我們可以看到它在Init方法中注冊了下面兩個事件

      application.PostResolveRequestCache += new EventHandler(this.OnApplicationPostResolveRequestCache);

      application.PostMapRequestHandler   += new EventHandler(this.OnApplicationPostMapRequestHandler);

       

      在此我們回顧下HttpApplication處理管線中的各種事件(已省略與本文無關(guān)的事件)

      1   請求驗證,檢查瀏覽器發(fā)送的信息,包括確定是否包含潛在的惡意標(biāo)記等。

      2   如果WebConfig中配置了UrlMappingsSection,則執(zhí)行URL映射

      3   引發(fā)BeginRequest事件

      ......

      ......

      9   引發(fā)PostResolveRequestCache事件

       

      10  引發(fā)MapRequestHandler事件:  

      根據(jù)所請求資源文件的擴(kuò)展名(在應(yīng)用程序的配置文件中映射),選擇對應(yīng)實現(xiàn)IHttpHandler接口的處理類。如果請求是aspx,并且需要對該頁進(jìn)行編譯,則asp.net會在獲取該頁面實例之前對其進(jìn)行編譯。

       

      11  引發(fā)PostMapRequestHandler事件

      ......

      ......

      15 調(diào)用第10步選擇的IHttpHandlerProcessRequest方法(或異步版的BeginProcessRequest

      ......

      ......

      22引發(fā)EndRequest事件

       

       

      上面黃色部分標(biāo)明的則是UrlRoutingModule所注冊的事件

       

      這兩個事件最開始都對HttpContext進(jìn)行再次封裝()

       

      【關(guān)于下文要提到的RouteRouteConllectionRouteData等的簡單結(jié)構(gòu)說明】

       

       

      附上源碼:

       

        RouteData routeData = this.RouteCollection.GetRouteData(context);
              if (routeData != null)
              {
                  IRouteHandler routeHandler = routeData.RouteHandler;
                  if (routeHandler == null)
                  {
                      throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, RoutingResources.UrlRoutingModule_NoRouteHandler, new object[0]));
                  }
                  if (!(routeHandler is StopRoutingHandler)) { RequestContext requestContext = new RequestContext(context, routeData);
                      IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext);
                      if (httpHandler == null)
                      {
                          throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, RoutingResources.UrlRoutingModule_NoHttpHandler, new object[] { routeHandler.GetType() }));
                      }
                      RequestData data2 = new RequestData {
                          OriginalPath = context.Request.Path,
                          HttpHandler = httpHandler
                      };
                      context.Items[_requestDataKey] = data2;
                      context.RewritePath("~/UrlRouting.axd");
                  }
              }
                

      說明:

       1 PostResolveRequestCache中做了如下處理:

      (1) 根據(jù)Url在路由表中查找匹配的路由獲得RouteData,即:

           遍歷RouteCollection集合,調(diào)用集合中Route(路由)GetRouteData方法,如果GetRouteData方法返回的RouteData對象不為空,則立即返回,這也就是說明了路由是按照路由設(shè)置的次序解析的,就算一個URL可以匹配多個路由,解析過程中一旦發(fā)現(xiàn)有匹配的路由就不會再進(jìn)行后面的路由檢索了,直接結(jié)束路由的解析過程。

       

      (2) 如果最終獲取到的RouteData不為空,獲取RouteDataRouteHandler屬性,RouteHandler是實現(xiàn)了IRouteHandler接口的,只有一個方法,那就是GetHttpHandler,此Handler(MvcRouteHandler)用于處理URL路由

       

      (3) 如果這個RouteHandler的類型不是StopRoutingHandler

      1)       封裝一個RequestContext類,此類只有兩個屬性,一個是之前的RouteData,還有就是封裝過后的contextHttpContextBase   

       

      2   調(diào)用之前(2)中RouteHandler中的GetHttpHandler方法傳入上一步的RequestContext參數(shù)將得到的HttpHandler,將其與當(dāng)前的請求路徑(context.Request.Path)一并封裝到RequestData對象中,并將RequestData存入context

       

       3  重寫路徑,指向UrlRouting.axd文件(context.RewritePath("~/UrlRouting.axd"),此文件是類似于aspx,實現(xiàn)了IHttpHandler接口。

       

      2   PostMapRequestHandler中做了如下處理:

       

      在此事件中要替換掉context中的handler  context中獲取到在之前這個PostResolveRequestCache事件中存入的RequestData,從RequestData獲取OriginalPath,將開始從寫路徑到UrlRouting.axd改回最開始狀態(tài)(即OriginalPath)讓輸出路徑和輸入路徑相同,同樣設(shè)置contextHandler為之前存入RequestDataHttpHandler

      這個Handler在配置路由表,往RouteConllection中存入Route實例化這個Route時被傳入

       

      3   HttpApplication處理管道后面事件中將會調(diào)用此HandlerMvcHandler)的ProcessRequest方法。

       

       

       

      寫到這里我產(chǎn)生了一個疑問?? 

      為什么在PostResolveRequestCache事件中將得到RequestData并存入Context 又在后面的PostMapRequestHandler事件中將其取出得到開始存入的Handler對象以及原始URL,并把重寫的路徑改回原始的URL再設(shè)置ContextHandler屬性,而不是這些過程全部都在PostMapRequestHandler這個事件中處理了,這么一存一放不是多此一舉嗎?

       

      至此我們再來研究下位于PostResolveRequestCache事件與PostMapRequestHandler事件之間的MapRequestHandler事件  

       

      之前的說明是:

      根據(jù)所請求資源文件的擴(kuò)展名(在應(yīng)用程序的配置文件中映射),選擇對應(yīng)實現(xiàn)IHttpHandler接口的處理類。如果請求是aspx,并且需要對該頁進(jìn)行編譯,則asp.net會在獲取該頁面實例之前對其進(jìn)行編譯。

       

      繼續(xù)查資料可以知道

         此事件只在IIS7.0的集成模式,且.Net Framework版本大于等于3.0的情況下才會觸發(fā),由于asp.net mvc請求的路徑并不會對應(yīng)一個文件,所以在此處會報錯,MS為了使處理模塊能夠在iis7中實現(xiàn)路由,則采取了這么一種簡單的解決辦法。先把路徑指向~/UrlRouting.axd,在此事件中會設(shè)置一個UrlRouting.axd類型的Handler避免報錯,并在下一步事件中替換掉此處的Handler再把~/UrlRouting.axd這個路徑給改回來。

       

      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  

       

       

      關(guān)于路由的使用:

      (對于已存在路徑的文件想要其不被路由:  

          RouteTable.Routes.RouteExistingFiles = false;

       

      一般通過Global.asax文件,在Application_Start()方法設(shè)置

       

      添加路由

      Example:

       

      routes.Add("Default", new Route

                  (

                      "{controller}/{action}/{id}",

                      new RouteValueDictionary { { "controller", "Home" }, { "action", "Index" }, { "id", UrlParameter.Optional } },

                      new MvcRouteHandler()

                  ));

                                              常量      控制器名     對應(yīng)的方法     變量username     變量password

      路由名

      routes.Add("Register", new Route

                  (

                      "Register/{controller}/{action}/{username}/{password}",

                      new RouteValueDictionary { { "controller", "Register" }, { "action", "RegisterUser" } },

                      new MvcRouteHandler()

                  ));

                                                                                        設(shè)置默認(rèn)值

       

       

      由于發(fā)布System.Web.Routing程序集之后MS也在不斷的改進(jìn),MS感覺上述路由的設(shè)置比較麻煩,但是此程序集又已經(jīng)發(fā)布了, 所以使用到.net 3.5 framework 新特性,擴(kuò)展方法,即可以在原有類別中添加新的實現(xiàn)方法,從而實現(xiàn)新的功能。

      位于System.Web.Mvc中的RouteCollectionExtensions類就是一個靜態(tài)類,其中定義的方法就是擴(kuò)展方法

      針對于路由集合類RouteCollection擴(kuò)展了兩類方法

      IgnoreRoute()

      MapRoute()

       

      對于MapRoute方法可以將上述代碼簡化為

       

      routes.MapRoute(

                      "Default",

                      "{controller}/{action}/{id}",

                      new { controller = "", action = "", id = UrlParameter.Optional }

                      );

       

                 routes.MapRoute(

                      "Register ",

                      "Register/{controller}/{action}/{username}/{password}",

                      new { controller = "Register", action = "RegisterUser" }

                      );

       

      忽略路由

       

      routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

       

      在上面的路由設(shè)置其中的路由名稱是可選的參數(shù),路由名稱可以用來生成URL路由,但其在路由解析中并沒有作用

      但是如果在視圖中生成相關(guān)的路由鏈接,可以直接指定路由名稱,加快檢索速度,使用指定路由的好處還有可以不必知名路由的其他參數(shù),例如控制器,控制方法等

       

      建議: 將常用的路由存放在路由表最前端

       

      自定義路由約束

       

      實現(xiàn)一個約束類:

       

      public class IDRouteConstraint: IRouteConstraint

          {

              #region IRouteConstraint Members

       

              public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)

              {

                  if ((routeDirection == RouteDirection.IncomingRequest)

                      && (parameterName.ToLower(CultureInfo.InvariantCulture) == "id"))

                  {

                      long id;

       

                      if (long.TryParse(values["id"].ToString(), out id))

                      {

                          if (id < 1000000 && id >= 0)

                          {

                              return true;

                          }

                      }

                  }

       

                  return false;

              }

       

              #endregion

          }

       

       

      在路由中配置

       

      routes.MapRoute(

                      "Default",

                      "{controller}/{action}/{id}",

                      new

                      {

                          controller = "Home", action = "Index", id="1001"

                      },

                      new

                      {

                          id = new IDRouteConstraint()

                      }

                  );

      posted on 2011-08-08 09:19  陽陽多  閱讀(1670)  評論(4)    收藏  舉報

      主站蜘蛛池模板: 日本乱码在线看亚洲乱码| 99久久国产精品无码| 人妻被猛烈进入中文字幕| 国产99视频精品免费视频36| 亚洲一区二区三区人妻天堂| 不卡av电影在线| 久久久久无码精品国产h动漫| 免费看欧美全黄成人片| 免费人成再在线观看视频| 二区三区亚洲精品国产| 狠狠色综合tv久久久久久| 欧美老少配性行为| 亚洲最大福利视频网| 亚洲a片无码一区二区蜜桃| 免费无码黄十八禁网站| 欧洲亚洲精品免费二区| 九九热在线精品视频九九| 日韩av第一页在线播放| 久久天天躁狠狠躁夜夜avapp| 国产精品白浆在线观看免费| 无码人妻精品一区二区三区下载| 亚洲熟女乱色一区二区三区| 性做久久久久久久久| 国产成人av电影在线观看第一页| 国产色无码专区在线观看| 少妇被粗大的猛烈进出动视频 | 99riav精品免费视频观看| 国产av永久无码天堂影院| 亚洲高请码在线精品av| 性欧美VIDEOFREE高清大喷水| 中文字幕乱码一区二区免费| 国产成人精品久久性色av| 中文字字幕在线中文乱码| 色偷偷女人的天堂亚洲网| 亚洲人妻一区二区精品| 国产精品中文字幕第一页| 欧美经典人人爽人人爽人人片| 在线无码午夜福利高潮视频| 欧美精品一区二区在线观看播放| 亚洲欧美中文字幕日韩一区二区| 欧美大胆老熟妇乱子伦视频|