中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

.NET/ASP.NET中Routing路由的示例分析

發布時間:2021-09-03 13:32:18 來源:億速云 閱讀:163 作者:小新 欄目:開發技術

這篇文章主要介紹了.NET/ASP.NET中Routing路由的示例分析,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

1】開篇介紹

ASP.NET Routing 系統是一切通過ASP.NET進行Uri訪問應用程序的基礎(并非物理文件的直接映射);隨著Routing的出現,我們的WEB設計已經和以前大不一樣;越來越輕量級、簡單化,都通過簡便的Uri資源的方式進行處理,將精力放在業務的設計上;現在主流的Rest ful api 也都是建立在這樣的一種機制下的,然而我們的ASP.NETMVC也是一種通過獨立的Uri進行程序訪問處理的框架,所以也是建立在ASP.NET Routing;再者就是現在也比較熱門的ASP.NET技術(ASP.NETWEBAPI);都是建立在Routing框架之上,可見它還是蠻重要的;

所以這篇文章讓我們來分析一下Routing的工作原理,它為什么能在不影響現有框架的基礎上提供這么好的擴展性,真的讓人很想去一探究竟;目前非常可觀是我們都了解ASP.NET現有的框架知識,我們大概了解它肯定是在ASP.NET管道模型的哪個位置進行了相應的攔截;

下面我們帶著這個重要的線索來一點一點弄清楚它是如何為其他框架做支撐的,我最疑惑的是它是如何將WebPage和MVC進行很好的區分的 ,最關鍵的是它如何做到只提供一個接口讓后續的相關框架都能基于這個公共的Routing接口進行擴展的,它的對象模型肯定很巧妙;我們需要去搞懂它,才能有信心去繼續我們的ASP.NET相關框架的后續學習;

注意:全文使用Routing一詞替代ASP.NETRouting一詞,特此說明,以免概念混淆;

2】ASP.NETRouting路由對象模型的位置

問到ASP.NET最重要的擴展點在哪里?我想我們都會異口同聲的說:在管道模型上,這也符合我們對此問題求解的一個基本思路;ASP.NET管道模型大家都懂的,在管道模型的相關事件中只要我們定義相關的事件就可以在管道的處理中插入自己的邏輯在里面;管道的最后執行接口是IHttpHander類型,只有阻止原本默認的IHttpHander接口創建才有可能改變整個的處理流程;

圖2.1:

.NET/ASP.NET中Routing路由的示例分析

那么Routing只有在阻止IHttpHander接口的創建前先執行,才能扭轉整個處理路線的機會,上圖中顯示的Application Event(2)(IHttpHander執行)意思是說只有在IHttpHander執行前的某個Application Event中進行Routing的執行才能在原本執行IHttpHander的地方執行其他定制的IHttpHander;而IHttpHander是ASP.NET框架的最終執行的接口,所以如果要想改變原本執行Page的Hander,需要提供自定義的IHttpHander接口對象;

換句話說,一切的執行入口其實在IHttpHander.ProcessRequest()方法中,但是現在矛盾的是ASP.NET Routing 卡在中間,它讓原本直接的處理流程變的有點撲簌迷離,它隔開了“ASP.NET基礎框架 " "基于ASP.NET的應用框架 "(如:ASP.NETMVC\ASP.NETWEBAPI\自定義框架)

注意:“ASP.NET基礎框架”指ASP.NET本身的框架可以理解為傳統的WEBFROM;而“基于ASP.NET的應用框架”是指基于ASP.NET基礎框架而設計的如:MVC\WEBPAGE\WEBAPI之類的上層輕量級應用框架;

圖2.2:

.NET/ASP.NET中Routing路由的示例分析

其實這幅圖很明了的表達式了ASP.NETRouting的位置,它是用來為ASP.NETASP.NETMVC、ASP.NETWEBAPI承上啟下的關鍵紐帶;根據上面我們的分析思路,Routing是ASP.NET框架直接交互的對象模型,所以站在ASP.NET的角度它是不知道背后究竟發生了什么事情,其實ASP.NETRouting已經在ASP.NETApplication某個生命事件中將原本的創建邏輯移花接木了;

3.】ASP.NETRouting路由對象模型的入口

Routing起到中間人的作用,將ASP.NET的相關邏輯透明包裝,我們雖然能在Routing的上層同樣可以使用相關的ASP.NET對象,但是概念已經發生了根本上的變化;我們可以隨意的引入自定義的IHttpHander實現類,根據前端傳過來的Uri進行策略執行,也就是說你完全可以定義一套自己內部使用的Uri規則和處理框架,建立在Routing基礎之上會很容易;

根據IHttpModule、IHttpHander 的相關的知識,我們很容易就能知道從哪里可以找到Routing的入口線索,如果我們都沒有猜錯的話在系統的Web.config文件中肯定有一個專門處理Routing的IHttpModule,利用來它將ASP.NETRouting對象植入到ASP.NET框架之中;

我們找到.NET Framework環境配置的地方:C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config 在該文件中我們可以找到系統級別的配置信息;

其實這里面配置的都是系統級別的選項,而我們程序里面使用的Web.config文件只是用來配置跟應用程序相關的選項,這樣的好處是我們可以在應用程序級別很方便的改變系統的默認配置;

我們找到httpModules配置節,在倒數第二行發現一個name為UrlRoutingModule-4.0的IHttpModule配置,應該就是它了,最關鍵的是它的type信息是System.Web.Routing.UrlRoutingModule 毋庸置疑了;

現在就好辦多了,我們只要順藤摸瓜就能找到UrlRoutingModule是如何工作的了,不過先不能急,還有些思路并不清晰,我們繼續慢慢分析;按照這樣的一個思路,基本上我們可以斷定UrlRoutingModule就是協調ASP.NETRouting框架的紐帶;

圖3.1:

.NET/ASP.NET中Routing路由的示例分析

此圖總結了我們到目前為止的一個基本思路,底層ASP.NET框架處理HTTP的對象化,然后通過ASP.NETRouting Module創建IHttpHandler接口對象,再然后就是執行IHttpHander接口,共三個步驟;

作為應用框架也就是最上層的代碼,如何才能決定ASP.NETRouting框架在處理ASP.NET的調用的時候能使用自己的IHttpHander接口對象,這個問題就需要我們深入的看一下ASP.NETRouting路由對象的內部對象模型了;

4.】ASP.NETRouting路由對象模型的內部結構

這里我將使用ASP.NETMVC作為應用框架來講解本例(目前我并不了解ASP.NETWEBAPI);那么ASP.NETMVC作為應用層框架,是如何讓ASP.NETRouting幫助轉換IHttpHander接口的呢,這就不得不去分析Routing一些列的對象之間的組成關系及互相作用了;

根據3.】小節,我們已經了解ASP.NETRouting是使用UrlRoutingModuel對象來作為ASP.NET管道的監聽者,然后根據一系列的內部處理得出最終的IHttpHander接口對象;那么要想搞清楚UrlRoutingModule是如何具體的協調這一切的,必須得深入的去分析源代碼才行,盡管我們只需要了解一個80%那也少不了這個環節;

注意:需要源代碼的朋友可以直接去一下站點獲取,微軟官方開源網站:http://www.codeplex.com/,開源中國:http://www.oschina.net/都可以找到源代碼;

4.1】UrlRoutingModule對象內部結構

首當其沖需要搞清楚的就是UrlRoutingModule對象,根據源碼指示我們基本上能確定幾個基本的原理,首先UrlRoutingModule繼承自IHttpModule接口,訂閱了Application.PostResolveRequstCache事件,在該事件中主要是通過全局路由對象表RouteTable對象獲取提供給上層使用的依賴注入接口IRouteHander接口;

【依賴注入接口】

這里需要解釋一下什么叫依賴注入接口,可以簡單的將依賴注入接口理解成提供給外界一個具體實現的機會;其實就是設計原則中的“依賴倒置原則”,在RouteData的內部不是直接依賴具體的對象;接口就是契約,提供一個接口就是約定雙方之間的契約;這里是約定了Routing框架將使用IRouteHander接口來獲取最后的處理IHttpHander接口;

下面我們將對UrlRoutingModule對象進行分析,由于我們分析源代碼是想搞清楚對象模型之間的操作流程及關系,所以不可能分析所有的代碼,我們的重點是搞清楚他們的執行順序及原理;由于UrlRoutingModule對象是導火線,它的出現將接二連三的牽連其他的對象出現,我們將分小節進行分析,交界處將一帶而過;

根據我們前面的分析思路,我們首先要找到UrlRoutingModule綁定Application事件的地方;

protected virtual void Init (HttpApplication application)
    {
      application.PostResolveRequestCache += PostResolveRequestCache;
    }

在PostResolverRequestCache方法中,我們將看到該方法調用了本地內部的一個同名方法:

void PostResolveRequestCache (object o, EventArgs e)

    {

      var app = (HttpApplication) o;

      PostResolveRequestCache (new HttpContextWrapper (app.Context));

    }

然后實例化了一個HttpContextWrapper包裝對象,傳入該同名方法;

public virtual void PostResolveRequestCache (HttpContextBase context)

    { 

      var rd = RouteCollection.GetRouteData (context); 

      //(1)匹配RouteData對象,后面分析; 

      var rc = new RequestContext (context, rd); 

      //(2)封裝計算出來的RouteData對象和當前HttpRequest對象; 

      IHttpHandler http = rd.RouteHandler.GetHttpHandler (rc);

      //(3)使用(1)步驟計算出來的當前RouteData對象中的RouteHander屬性獲取路由處理程序IHttpHander接口

      context.Request.RequestContext = rc;

      context.RemapHandler (http);

    }

當然我已經省略了部分不太相關的代碼,畢竟要想說清楚所有的代碼一篇文章顯然是不夠的;上述代碼中我用紅色標記出重要的部分;

首先是第一個重要點(1),匹配RouteData對象;其實就是我們在程序里面配置的Url模板數據,當請求來的時候我們需要去根據當前請求的Url到路由表去匹配是否有符合當前Url的路由對象;

routes.MapRoute(

        name: "Default",

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

        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }

其實就是對應著本段代碼的配置,這段代碼處理后將是一個Route對象實例,而上面的RouteCollection就很好理解了,它是Route的強類型集合;

到目前為止,已經出現了好幾個跟Route相關的對象,沒關系,當我們將整條線分析到頭時將很清楚他們的作用;

第二個重要點(2),封裝RequestContext對象,其實我們從類型的名稱上就能確定它的用途,它是請求上下文,也是有界上下文;這里面封裝了在下面獲取IHttpHander接口時將需要當作參數;

第三個重點(3),利用前面的匹配得到的RouteData對象,其實RouteData是路由數據的意思,那么什么叫路由數據:就是路由匹配成功后所生成的和路由相關的數據;還記得我們在3】節分析的原理嗎,UrlRoutingModule對上層提供基本的路由功能,但是具體的處理是在應用層面上;

那么就是這里通過RouteData.RouteHandler.GetHttpHandler(RequestContext requestContext) 方法獲取到的最終頂層應用處理器;

圖4.1:

.NET/ASP.NET中Routing路由的示例分析

上面的解釋可以使用這幅圖來簡單的表達;

UrlRoutingModule對象通過RouteData路由數據對象獲取IRouteHander接口,然后通過IRouteHander接口獲取最終的IHttpHander接口;

小結:其實可以將UrlRoutingModule對象理解成是ASP.NETRouting模塊的基礎部分,而擴展的地方則在我們應用程序配置的地方,也就是我們通常在Global.asax.cs文件中配置的路由數據;當我們在配置Route對象的時候其實已經指定了IRouteHander接口,然后這個接口會被放入RouteData同名屬性中,而不是作為零散的對象被UrlRoutingModule直接獲取;

4.2】RouteBase、Route、RouteCollection、RouteTable路由核心對象模型

在4.1 】節中,UrlRoutingModule是路由框架的基礎設施部分,內置于. NETFramework系統及ASP.NET配置之中web.config;在ASP.NET進行版本升級的時候該部分工作已經由系統自動幫我們升級,我們在使用的時候只需要創建ASP.NET3.5 SP1以上的版本都會自動擁有路由系統功能,因為根據微軟官方MSDN介紹,路由系統是在ASP.NET3.5 SP1中引入的;其實我們大部分使用的ASP.NET版本已經是4.5的,就算以前是2.0、3.0的版本也會陸續升級到最新的版本;因為新版本的框架提供了無數個讓你無法拒絕的優勢;

那么當基礎部分有了之后我們能做到就是應用編程接口的編程,其實這部分才是我們接觸的地方;而這一小節我們將重點分析路由系統提供給我們應用層面的編程接口,也就是上面標題列出的幾個核心對象;

先基本介紹一下這幾個對象的意思和彼此之間的關系:

RouteBase:很明顯是Route的基類,提供了作為自定義路由對象的頂層抽象,所有的路由框架的內部均使用抽象的RouteBase為依賴;

Route:路由系統默認實現的路由對象繼承自RouteBase抽象基類,用來作為我們默認的路由配置對象,當然你可以可是實現自己的Route對象;

RouteCollection:Route作為單個Url的配置,那么系統中肯定會有多個Url規則的配置,所以RouteCollection對象是表示Route的強類型集合,該類繼承自 Collection<RouteBase> 類型;所以RouteCollection是用來作為Route的集合管理用的;注意這里的泛型Collection<T>中的RouteBase,再一次提醒我們要“依賴倒置”;

RouteTable:用來存放RouteCollection對象,路由表中有一系列的路由對象,而這一系列的對象就是RouteCollection管理的;在RouteTable中用Routes靜態屬性表示當前系統全局的路由映射表;

這里很明顯能看出來對路由的一層一層抽象,從簡單的Route表示一個路由映射,再到表示Route的集合RouteCollection,再到最后的RouteTable的,抽象的很OO;

為了讓大家對上面這些對象的解釋有一個直觀的認識,我們用一張圖來解釋他們如何關聯和執行流程;

圖4.2:

.NET/ASP.NET中Routing路由的示例分析

下面我們將深入到各個對象的內部去摸索一下他們之間的交互,我們根據這種引用關系來分析,首先是Route對象;

【Route、RouteBase】

Route對象繼承自RouteBase代表一個Url模板的配置,包括Url的模板的字符串,如:api/order/102304,還有一些輔助性的內容,這不是本節的重點,我們只要知道它是用來做Url的配置即可; Route對象不是直接被我們實例化的,而是通過應用層的擴展方法進行實例化,為什么要這么做,其實這里就是路由為什么能轉到上層的關鍵點;

根據ASP.NETMVC中的路由集合擴展類,也就是System.Web.Mvc.RouteCollectionExtensions靜態類中的擴展方法,這些擴展方法就是用來包裝我們在應用ASP.NET的時候配置Route使用的;是否還記得我們第4】節的一開始介紹了一個依賴注入接口的原理,這里將通過依賴注入接口達到外掛自定義實現的目的;

在Route源碼中,我們將看到它有一個IRouteHander接口類型的屬性RouteHander;

public class Route : RouteBase

{

 public IRouteHandler RouteHandler { get; set; } 

}

這個IRouteHandler接口類型的屬性就是我們ASP.NETMVC將要實現的一個IRouteHandler接口;而這個接口的定義:

public interface IRouteHandler

{

  IHttpHandler GetHttpHandler (RequestContext requestContext);

}

很簡單,就是為了創建出ASP.NET管道引擎最后執行的IHttpHandler接口; Route類有一個重寫了RouteBase的核心方法:

public override RouteData GetRouteData (HttpContextBase httpContext)

該方法是用來獲取當前路由的一些匹配數據的,關于RouteData在4.1】節介紹過,詳細我們將看下面關于對它的詳細分析,這里將不做介紹了;

小結:其實Route對象還算簡單,關鍵的兩點就是GetRouteData方法和IRouteHander接口,前者是用來獲取當前路由匹配成功后的路由信息,而后者是用來返回最終要執行的IHttpHandler接口;

【RouteCollection、RouteTable】

RouteCollecton和RouteTable對象比較簡單;我們先來看RouteCollection對象,首先你可能會有疑問,為什么不用一個簡單的Collection類型的對象來存放Route實例,非要實現了一個RouteCollection;不看源碼還真不知道它內部做了很多工作,首先最重要的就是線程并發情況下的Look機制;由于我們的RouteCollection對象是全局靜態對象,會同時存在著多個線程并發的讀取這個對象,所以必須在對集合訪問的時候進行互斥控制;比如說這段代碼:

public void Add (string name, RouteBase item)

{

  lock (GetWriteLock ()) {

    base.Add (item);

    if (!String.IsNullOrEmpty (name))

      d.Add (name, item);

  }

}

在添加路由的時候首先鎖住寫入對象,然后才能安全的進行操作;我們接著RouteTable對象,這個對象最簡單,就是一個靜態屬性Routes用來存放全局路由表;

public class RouteTable

{

  static RouteTable ()

  {

    Routes = new RouteCollection ();

  } 

  public static RouteCollection Routes { get; private set; }

}

當首次獲取Routes屬性時,會在靜態構造函數中實例化RouteCollection對象;

4.3】RouteValueDictionary、RouteData、RequestContext 路由數據對象模型

在第4.2】小節中,我們分析了路由系統的幾個核心對象,但是核心對象要想運行起來中間必須有一些數據封裝的對象為他們消除數據傳遞的問題;而這小節的三個核心對象真是路由系統能成功工作的必不可少的數據存放、數據傳輸容器的核心對象;

先基本介紹一下這幾個對象的意思和彼此之間的關系:

RouteValueDictionary:路由對象內部存放中間值使用的對象,比如Url模板的默認值,命名空間,地址欄傳過來的參數等等;當然也可以用來存放任何Key-Value形式的任何值;

RouteData:路由數據,用來包裝根據路由Url匹配成功后的路由數據封裝,最重要的是將IRouteHander接口傳遞到UrlRoutingModule中去;

RequestContext:請求上下文,將HttpRequest、RouteData包裝起來傳入IRouteHander接口獲取IHttpHander接口;因為IRouteHandler接口方法GetHttpHandler需要知道當前請求的一些信息和根據當前Url處理后的路由數據才能計算出當前的IHttpHandler接口;

為了讓大家對上面這些對象的解釋有一個直觀的認識,我們用一張圖來解釋他們如何關聯和執行流程;

圖4.3:

.NET/ASP.NET中Routing路由的示例分析

下面詳細的分析每個對象的內部原理;

【RouteValueDictionary】

RouteValueDirctionary對象是在路由對象內部存放數據用的,比如:我們在配置路由的時候,可以指定一些默認值、命名空間等等;

看RouteValueDictionary源碼定義:

public class RouteValueDictionary : IDictionary<string, object>

該類型繼承自字典接口IDictionary<string,object>,繼承自字典接口而不是繼承自字典基類目的只是想使用字典的行為而不是它的默認實現;在RouteValueDictionary內部使用了一個Dictionary<string,object>類型作為最終容器;

Dictionary<string,object> d = new Dictionary<string,object> (CaseInsensitiveStringComparer.Instance);

在構造函數中使用了一個內部類CaseInsensitiveStringComparer進行Key的相等比較:

internal class CaseInsensitiveStringComparer : IEqualityComparer<string>

    {

      public static readonly CaseInsensitiveStringComparer Instance = new CaseInsensitiveStringComparer (); 

      public int GetHashCode (string obj)

      {

        return obj.ToLower (CultureInfo.InvariantCulture).GetHashCode ();

      } 

      public bool Equals (string obj1, string obj2)

      {

        return String.Equals (obj1, obj2, StringComparison.OrdinalIgnoreCase);

      }

    }

IEqualityComparer接口還是很不錯的,不過現在基本上不這么用了,而是直接提供了一個Lambda做為比較函數;

【RouteData】

路由數據對象,它的大概意思我想大家應該知道了,上面提到過很多次,這里就不介紹了;我們直接看一下RouteData內部核心代碼段:

public RouteData (RouteBase route, IRouteHandler routeHandler)

{

  Route = route;

  RouteHandler = routeHandler; 

  DataTokens = new RouteValueDictionary ();

  Values = new RouteValueDictionary ();

} 

public RouteValueDictionary DataTokens { get; private set; } 

public RouteBase Route { get; set; } 

public IRouteHandler RouteHandler { get; set; } 

public RouteValueDictionary Values { get; private set; }

通過構造函數我們能了解到,保存了對Route對象的引用和IRouteHander接口的引用,為什么將IRouteHandler作為構造函數參數,那是因為RouteBase根本沒有對IRouteHander接口的屬性定義;IRouteHandler接口在不在RouteBase或Route中不重要,因為Route可以是自定義的,這里的強制性是在RouteData中,它的構造函數必須接受IRouteHandler類型接口;

我們接著看,在構造函數的下面兩行代碼中分別是實例化了DataTokens、Values兩個屬性,而類型是RouteValueDictionary,這也剛好和我們上面分析的對上了;RouteValueDictionary是內部用來保存這些零散鍵值對數據容器,在Route、RouteData還有其他地方均需要用到;就是因為RouteValueDictionary的Value是Object類型,所以可以用來存放任何類型的值,比較通用;

【RequestContext 】

RequestContext在上面也已經接觸很多次了,表示請求上下文,也就是跟當請求相關的所有數據都封裝在里面;在后面的文章中,我們將接觸很多類似Context的對象,如:ControlContext,ViewContext之類的,都是用來控制上下文的邊界,而不是直接傳遞零散的參數;

4.4】IRouteHandler 、IHttpHander兩個接口之間的關系

IRouteHandler接口是路由框架起作用的核心,只有提供了IRouteHandler實現才能順利的得到背后的IHttpHandler接口;ASP.NETMVC提供了MvcRouteHandler對象來實現IRouteHandler接口,MvcRouteHandler在內部實例化實現了IHttpHandler接口的MvcHandler對象;MvcHandler然后通過RequestContext對象獲取RouteData對象,接著得到相應的Control信息,進行后續的執行處理;

5.】UrlRoutingHandler 對象內部結構及擴展應用

在ASP.NETRouting路由框架中有一個很重要的IHttpHandler接口對象UrlRoutingHanlder,我想你肯定很疑惑,為什么需要這樣一個對象;其實它的存在是為了提供給我們繞過UrlRoutingModule模塊的機會;根據上面的詳細的分析,我們知道路由的入口在UrlRoutingModule,所有的路由相關的映射工作都在該類中完成,但是有時候我們很想繞過UrlRoutingModule進行簡單的處理或者性能方面的優化考慮,這就派上用場了;我能想到的使用場景目前來看是對ASP.NET第版本的項目做Url重寫是比較方便,首先我們的項目需要建立在低版本的ASP.NET之上,但是需要添加Url.ReWriter的功能,就需要我們自己去實現這樣的功能;

但是工作量和性能都很難控制好,如果使用這里提供的UrlRoutingHandler進行實現就很方便了,UrlRoutingHandler給我們使用ASP.NETRouting框架的機會同時也不需要關心是否配置了UrlRoutingModule;

public abstract class UrlRoutingHandler : IHttpHandler

根據代碼看出它是一個抽象類,直接實現IHttpHanlder接口,但是重要的是ProcessRequest方法;

protected virtual void ProcessRequest (HttpContextBase httpContext)

    {

      if (httpContext == null)

        throw new ArgumentNullException ("httpContext"); 

 

      var rd = RouteCollection.GetRouteData (httpContext);

      if (rd == null)

        throw new HttpException ("The incoming request does not match any route");

      if (rd.RouteHandler == null)

        throw new InvalidOperationException ("No IRouteHandler is assigned to the selected route"); 

 

      RequestContext rc = new RequestContext (httpContext, rd); 

 

      var hh = rd.RouteHandler.GetHttpHandler (rc);

      VerifyAndProcessRequest (hh, httpContext);

    } 

 

    protected abstract void VerifyAndProcessRequest (IHttpHandler httpHandler, HttpContextBase httpContext);

該方法的邏輯跟UrlRoutingModule里的PostResolveRequestCache方法是差不多的,都會通過全局RouteCollection集合進行匹配當前的RouteData對象;那就足夠說明這個過程不會再通過UrlRoutingModule模塊;方法的最后一行是執行一個模板方法:VerifyAndProcessRequest ,該方法是留給子類去實現的;

那么這里將路由和執行合在一起了,基類負責路由子類負責執行,很不錯的設計方法;

感謝你能夠認真閱讀完這篇文章,希望小編分享的“.NET/ASP.NET中Routing路由的示例分析”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

向AI問一下細節

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

AI

绵竹市| 甘谷县| 包头市| 二连浩特市| 乐亭县| 新干县| 泰来县| 淮北市| 威海市| 辽宁省| 塔河县| 基隆市| 同德县| 陆川县| 普兰店市| 沙雅县| 大埔县| 蛟河市| 忻城县| 乐安县| 金塔县| 普兰店市| 蒲江县| 连南| 林口县| 宜宾县| 泽普县| 买车| 天台县| 胶州市| 蕉岭县| 枝江市| 济源市| 谢通门县| 尼勒克县| 怀远县| 临城县| 黄龙县| 阳东县| 山东省| 双江|