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

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

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

      ASP.NET MVC是如何運行的[2]: URL路由

      在一個ASP.NET MVC應用來說,針對HTTP請求的處理和相應定義Controller類型的某個Action方法中,每個HTTP請求的目標對象不再像ASP .NET Web Form應用一樣是一個物理文件,而是某個Controller的某個Action。目標Controller和Action的名稱包含在HTTP請求中,而ASP.NET MVC的首要任務就是通過當前HTTP請求的解析得到正確的Controller和Action的名稱。這個過程是通過ASP.NET MVC的URL路由機制來實現的。

      一、RouteData

      ASP.NET定義了一個全局的路由表,路由表中的每個路由對象對應著一個將Controller和Action名稱作為站位符的URL模板。對于每一個抵達的HTTP請求,ASP.NET MVC會遍歷路由表找到一個URL模板的模式與請求地址相匹配的路有對象,并最終解析出以Controller和Action名稱為核心的路由數據。在我們自定義的ASP.NET MVC框架中,路由數據通過具有如下定義的RouteData類型表示。

         1: public class RouteData
         2: {
         3:     public IDictionary<string, object> Values { get; private set; }
         4:     public IDictionary<string, object> DataTokens { get; private set; }
         5:     public IRouteHandler RouteHandler { get;  set; }
         6:     public RouteBase Route { get; set; }
         7:  
         8:     public RouteData()
         9:     {
        10:         this.Values = new Dictionary<string, object>();
        11:         this.DataTokens = new Dictionary<string, object>();
        12:         this.DataTokens.Add("namespaces", new List<string>());
        13:     }
        14:     public string Controller
        15:     {
        16:         get
        17:         {
        18:             object controllerName = string.Empty;
        19:             this.Values.TryGetValue("controller", out controllerName);
        20:             return controllerName.ToString();
        21:         }
        22:     }
        23:     public string ActionName
        24:     {
        25:         get
        26:         {
        27:             object actionName = string.Empty;
        28:             this.Values.TryGetValue("action", out actionName);
        29:             return actionName.ToString();
        30:         }
        31:     } 
        32:     public IEnumerable<string> Namespaces
        33:     {
        34:         get
        35:         {
        36:             return (IEnumerable<string>)this.DataTokens["namespaces"];
        37:         }
        38:     } 
        39: }

      從上面的代碼片斷所示,RouteData定義了兩個字典類型的屬性Values和DataTokens,前者代表直接從請求地址解析出來的變量,后者代表其他類型的變量。表示Controller和Action名稱的同名屬性直接從Values字典中提取,對應的Key分別為controller和action。屬性Namespaces表示輔助Controller類型的解析而設置的命名空間列表,該屬性值從DataTokens字典中提取,對應的Key為namespaces。

      我們之前已經提到過ASP.NET MVC本質上是兩個自定義的ASP.NET組件來實現的,一個是自定義的HttpModule,另一個是自定義的HttpHandler,而后者從RouteData的RouteHandler屬性獲得。RouteData的RouteHandler屬性類型為IRouteHandler接口,如下面的代碼片斷所示,該接口具有一個唯一的GetHttpHandler用于返回真正用于處理HTTP請求的HttpHandler對象。

         1: public interface IRouteHandler
         2: {
         3:     IHttpHandler GetHttpHandler(RequestContext requestContext);
         4: }

      IRouteHandler接口的GetHttpHandler方法接受一個類型為RequestContext的參數。顧名思義,RequestContext表示當前(HTTP)請求的上下文,其核心就是對當前HttpContext和RouteData的封裝,這可以通過如下的代碼片斷看出來。

         1: public class RequestContext
         2: {
         3:     public virtual HttpContextBase HttpContext { get; set; }
         4:     public virtual RouteData RouteData { get; set; }
         5: }

      二、Route和RouteTable

      RouteData具有一個類型為RouteBase的Route屬性,表示當前路由表中與當前請求匹配的路由對象。換句話說,當前的RouteData就是通過該路由對象針對當前HTTP請求進行解析獲得的。RouteBase是一個抽象類,如下面的代碼片斷所示,它僅僅包含一個GetRouteData方法,該方法通過對以HttpContextBase對象表示的當前HTTP上下文進行解析從而獲取一個RouteData對象。

         1: public abstract class RouteBase
         2: {
         3:     public abstract RouteData GetRouteData(HttpContextBase httpContext);
         4: }

      ASP.NET MVC提供的基于URL模板的路由機制是通過具有如下定義的Route類型實現的。Route是RouteBase的子類,字符串類型的Url屬性代表定義的URL模板 。在實現的GetRouteData方法中,通過HttpContextBase獲取相對請求地址,如果該地址與定義在模板中的URL模式相匹配則創建一個RouteData返回;否則返回Null。對于返回的RouteData對象,其Values屬性表示的字典包含直接通過地址解析出來的變量,而對于DataTokens字典和RouteHandler屬性,則直接取自Route對象的同名屬性。

         1: public class Route : RouteBase
         2: {
         3:     public IRouteHandler RouteHandler { get; set; }
         4:     public Route()
         5:     {
         6:         this.DataTokens = new Dictionary<string, object>();
         7:         this.RouteHandler = new MvcRouteHandler();
         8:     }
         9:     public override RouteData GetRouteData(HttpContextBase httpContext)
        10:     {
        11:         IDictionary<string, object> variables;
        12:         if (this.Match(httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(2), out variables))
        13:         {
        14:             RouteData routeData = new RouteData();
        15:             foreach (var item in variables)
        16:             {
        17:                 routeData.Values.Add(item.Key, item.Value);
        18:             }
        19:             foreach (var item in DataTokens)
        20:             {
        21:                 routeData.DataTokens.Add(item.Key, item.Value);
        22:             }
        23:             routeData.RouteHandler = this.RouteHandler;
        24:             return routeData;
        25:         }
        26:         return null;
        27:     }
        28:     public string Url { get; set; }
        29:     public IDictionary<string, object> DataTokens { get; set; }
        30:     protected bool Match(string requestUrl, out IDictionary<string,object> variables)
        31:     {
        32:         variables = new Dictionary<string,object>();
        33:         string[] strArray1 = requestUrl.Split('/');
        34:         string[] strArray2 = this.Url.Split('/');
        35:         if (strArray1.Length != strArray2.Length)
        36:         {
        37:             return false;
        38:         }
        39:  
        40:         for (int i = 0; i < strArray2.Length; i++)
        41:         { 
        42:             if(strArray2[i].StartsWith("{") && strArray2[i].EndsWith("}"))
        43:             {
        44:                 variables.Add(strArray2[i].Trim("{}".ToCharArray()),strArray1[i]);
        45:             }
        46:         }
        47:         return true;
        48:     }
        49: }

      由于同一個Web應用可以采用多種不同的URL模式,所以也需要注冊多個繼承自RouteBase的路由對象對它們進行解析,多個路由對象組成了一個路由表。在我們自定義ASP.NET MVC框架中,路由表通過類型RouteTable表示。如下面的代碼片斷所示,RouteTable僅僅具有一個類型為RouteDictionary的Routes屬性表示針對真個Web應用的全局路由表。

         1: public class RouteTable
         2: {
         3:     public static RouteDictionary Routes { get; private set; }
         4:     static RouteTable()
         5:     {
         6:         Routes = new RouteDictionary();
         7:     }
         8: }

      RouteDictionary表示一個具名的路由對象的列表,我們直接讓它繼承自Dictionary<string, RouteBase>類型,其中的Key表示注冊的路由對象的名稱。在GetRouteData方法中,我們遍歷集合找到與指定的HttpContextBase對象匹配的路由對象,并得到對應的RouteData。

         1: public class RouteDictionary: Dictionary<string, RouteBase>
         2: {
         3:     public RouteData GetRouteData(HttpContextBase httpContext)
         4:     {
         5:         foreach (var route in this.Values)
         6:         {
         7:             RouteData routeData = route.GetRouteData(httpContext);
         8:             if (null != routeData)
         9:             {
        10:                 return routeData;
        11:             }
        12:         }
        13:         return null;
        14:     }
        15: }

      在Global.asax中我們創建了一個基于指定URL模板的Route對象,并將其添加到通過RouteTable的靜態只讀屬性Routes表示的全局路由表中。

      三、UrlRoutingModule

      路由表的目的在于對當前的HTTP請求進行解析從而獲取一個以Controller和Action名稱為核心的路由數據,即上面介紹的RouteData,而整個解析工作是通過一個類型為UrlRoutingModule的自定義HttpModule來完成的。如下面的代碼片斷所示,在實現了接口IHttpModule的UrlRoutingModule類型的Init方法中,我們注冊了HttpApplicataion的PostResolveRequestCache事件。

         1: public class UrlRoutingModule: IHttpModule
         2: {
         3:     public void Dispose()
         4:     {}
         5:     public void Init(HttpApplication context)
         6:     {
         7:         context.PostResolveRequestCache += OnPostResolveRequestCache;
         8:     }
         9:     protected virtual void OnPostResolveRequestCache(object sender, EventArgs e)
        10:     {
        11:         HttpContextWrapper httpContext = new HttpContextWrapper(HttpContext.Current);
        12:         RouteData routeData = RouteTable.Routes.GetRouteData(httpContext);
        13:         if (null == routeData)
        14:         {
        15:             return;
        16:         }
        17:         RequestContext requestContext = new RequestContext { RouteData = routeData, HttpContext = httpContext };
        18:         IHttpHandler handler = routeData.RouteHandler.GetHttpHandler(requestContext);
        19:         httpContext.RemapHandler(handler); 
        20:     }
        21: }

      當PostResolveRequestCache事件觸發之后,UrlRoutingModule通過RouteTable的靜態只讀屬性Routes得到表示全局路由表的RouteDictionary對象,然后調用其GetRouteData方法并傳入用于封裝當前HttpContext的HttpContextWrapper對象(HttpContextWrapper是HttpContextBase的子類)并得到一個封裝了路由數據的RouteData對象。如果得到的RouteData不為空,根據該對象本身和和之前得到的HttpContextWrapper對象創建一個表示當前請求上下文的RequestContext對象,將其作為參數傳入RouteData的RouteHandler的GetHttpHandler方法得到一個HttpHandler對象。最后我們調用HttpContextWrapper對象的RemapHandler方法對得到HttpHandler進行映射,這意味著該HttpHandler將最終用于處理當前的HTTP請求。

      ASP.NET MVC是如何運行的[1]: 建立在“偽”MVC框架上的Web應用
      ASP.NET MVC是如何運行的[2]: URL路由
      ASP.NET MVC是如何運行的[3]: Controller的激活
      ASP.NET MVC是如何運行的[4]: Action的執行

      posted @ 2012-03-11 20:25  Artech  閱讀(20482)  評論(21)    收藏  舉報
      主站蜘蛛池模板: 狠狠色综合久久狠狠色综合| 亚洲AV无码一二区三区在线播放| 最近中文字幕国产精品| 亚洲一区三区三区成人久| 大地资源网中文第五页| 亚洲av肉欲一区二区| 国内极度色诱视频网站| 国产高清视频一区二区乱| 四虎国产精品永久在线下载| 亚洲欧洲日韩精品在线| 欧美成人精品三级网站| 精品久久久久久无码免费| 国产高清视频一区二区三区| 国产亚洲精品在av| WWW丫丫国产成人精品| 久久久久99精品成人片牛牛影视| 人妻精品动漫H无码中字| 精品久久久久中文字幕日本| 少妇无套内射中出视频| 平阴县| 美女一区二区三区亚洲麻豆| 大香伊蕉在人线国产最新2005| 最新偷拍一区二区三区| 亚洲精品久荜中文字幕| 亚洲人午夜精品射精日韩| 日韩乱码人妻无码中文字幕视频 | 国产精品无码专区| 四虎国产精品久久免费地址| 亚洲日韩中文字幕在线播放 | 免费中文熟妇在线影片| 国产乱色熟女一二三四区| 国产成人精品亚洲资源| 在线视频中文字幕二区| 免费人成再在线观看视频| 国产制服丝袜无码视频| 高清偷拍一区二区三区| 亚洲日韩av在线观看| 国产农村老熟女国产老熟女| 镇雄县| 免费无码国模国产在线观看| 少妇办公室好紧好爽再浪一点|