【ASP.NET MVC系列】淺談ASP.NET MVC 路由

ASP.NET MVC系列文章html

【01】淺談Google Chrome瀏覽器(理論篇)ios

【02】淺談Google Chrome瀏覽器(操做篇)(上)web

【03】淺談Google Chrome瀏覽器(操做篇)(下)正則表達式

【04】淺談ASP.NET框架   算法

【05】淺談ASP.NET MVC運行過程    express

【06】淺談ASP.NET MVC 控制器   瀏覽器

【07】淺談ASP.NET MVC 路由   緩存

【08】淺談ASP.NET MVC 視圖 安全

【09】淺談ASP.NET MVC 視圖與控制器傳遞數據服務器

【10】淺談jqGrid 在ASP.NET MVC中增刪改查     

【11】淺談ASP.NET 頁面之間傳值的幾種方式

【12】淺談緩存技術在ASP.NET中的運用       

【13】淺談NuGet在VS中的運用      

【14】淺談ASP.NET 程序發佈過程           

【15】淺談數據註解和驗證           

【16】淺談依賴注入

【17】淺談表單和HTML輔助方法

【18】淺談基於APS.NET身份驗證

【19】淺談ASP.NET MVC 模型

【20】淺談ASP.NET MVC 單元測試

【21】淺談ASP.NET MVC網絡安全;

【22】淺談ASP.NET MVC八大類擴展

【23】再談ASP.NET MVC Routing

【24】淺談ASP.NET 高級話題

【25】淺談大型ASP.NET MVC項目(含DEMO)

【26】下一系列:ASP.NET WebAPI


 

例子引入

 先看看以下例子,你能徹底明白嗎?

 1 using System;  2 using System.Collections.Generic;  3 using System.Linq;  4 using System.Web;  5 using System.Web.Mvc;  6 using System.Web.Routing;  7 
 8 namespace MVCDemo  9 { 10     public class RouteConfig 11  { 12         public static void RegisterRoutes(RouteCollection routes) 13  { 14             routes.MapMvcAttributeRoutes();//特性路由
15 
16             routes.IgnoreRoute("{resource}.axd/{*pathInfo}");//忽略資源文件
17 
18  routes.MapRoute( 19                 name: "Default",//路由名,惟一
20                 url: "{controller}/{action}/{id}",//路由URL
21                 defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },//路由URL默認值
22                 namespaces: new[] { "MVCDemo.Controllers" },//命名空間避免二義性
23                 constraints: new { id = @"^\d*$" }//約束
24 
25  ); 26  } 27  } 28 }

注:該例子沒有加入區域

1 URI、URL與URN

 1.1 URI、URL和URN定義 

     URI(Uniform Resource Identifier)表明統一資源標識符,標識資源的字符串;

     URL (Uniform Resource Locator)表明統一資源定位符,互聯網上標準資源的地址;

     URN(Uniform Resources Name)表明統一資源名稱,互聯網上資源的名稱;

 1.2 URI、URL和URN三者之間的關係圖

1.3 對URI、URL和URN三者之間解析

      本解析基於1.2 URI、URL和URN三者之間的關係圖。

      (1)從命名角度,URI標識資源且惟一,URL標識資源地址 ,URN標識資源名稱;

      (2)從數學關係:URI=URL+URN+URL∩URN;很容易看出,URL必定是URI,但URI不必定是URL,同理,URN必定是URI,但URI不必定是URN;

1.4 URL應具備特色

     (1)  域名便於記憶和拼寫;

     (2)  簡短;

     (3)  便於輸入;

     (4)  能夠反映出站點結構;

     (5)  應該是「可破解的」,用戶能夠經過移除URL的末尾,進而到達更高層次的信息體系結構;

     (6)  持久、不能改變

1.5  小結

       一般狀況下,URI表明贊成資源標識符(Uniform Resource Identifier)。URI是標識了一個資源的字符串。從技術角度看,全部URL都是URI。W3C認爲「URL是一個非正式的概念,但它很是有用:URL是URI的一種類型,它經過表示自身的主要訪問機制來標識資源」,換句話說,URI是某種資源的標識符,而URL則爲獲取該資源提供了具體的信息。

       註釋:資源是一個抽象概念,既能夠指一個文件,也能夠指方法調用的結果或服務器上的一些其餘內容。

2 路由概述(傳統路由)

2.1  WebForm URL與Route URL

     (1)WebForm中,對URL的傳入請求一般映射到磁盤上的物理文件,如.aspx文件。例如對http://server/application/Product.aspx?id=4的請求映射到名爲Products.aspx文件,該文件包含代碼和標記用於呈現對瀏覽器的響應,通常請求示過程抽象以下:

     

     (2)ASP.NET MVC中,一般地,URL映射並不是映射到具體磁盤上的物理文件,這是基於ASP.NET路由特性,主要有兩個過程,即URL映射和URL生成(接下來說解)。在ASP.NET路由中,您能夠定義URL模式,該模式包含在處理URL請求時使用的值的佔位符。在運行時,運用程序名稱後面的URL部分根據您所定義的URL模式分析爲離散值。例如,在請求http://server/application/Products/show/beverages時,路由分析器能夠將值Products、show和beverages傳遞給請求的處理程序。相反,在一個不禁URL路由管理的請求中,/Products/show/beverages片斷將被解釋爲運用程序中的一個文件的路徑。   

2.2  ASP.NET 路由與 URL 重寫

        ASP.NET 路由不一樣於其餘 URL 重寫方案。URL 重寫經過在將請求發送到網頁以前實際更改 URL 來處理傳入請求。例如,一個使用 URL 重寫的應用程序可能會將 URL 從 /Products/Widgets/ 更改成 /Products.aspx?id=4。此外,URL 重寫一般沒有相應的 API 來建立基於模式的 URL。在 URL 重寫中,若是更改了 URL 模式,則必須手動更新包含原始 URL 的全部超連接。因爲 ASP.NET 路由能夠從 URL 提取值,因此處理傳入請求時不更改 URL。若是必須建立一個 URL,則將參數值傳遞到爲您生成 URL 的方法中。若要更改 URL 模式,請在某位置更改該模式,您在應用程序中建立的基於該模式的全部連接將自動使用新模式。

2.3  路由定義

        A route is a URL pattern that is mapped to a handler. The handler can be a physical file, such as an .aspx file in a Web Forms application. A handler can also be a class that processes the request, such as a controller in an MVC application. To define a route, you create an instance of the Route class by specifying the URL pattern, the handler, and optionally a name for the route.

       譯文:路由是一種被映射到某個處理程序的URL模式。處理程序多是一個物理文件,如在WebForms運用程序中的aspx文件。處理程序也多是一個處理請求的類,如MVC應用程序中的控制器。要定義路由,您能夠經過指定URL模式、處理程序和路徑的名稱來建立路由類的實例。

      You add the route to the application by adding the Route object to the static Routes property of the RouteTable class. The Routes property is a RouteCollection object that stores all the routes for the application.You typically do not have to write code to add routes in an MVC application. Visual Studio project templates for MVC include preconfigured URL routes. These are defined in the MvcApplication class, which is defined in the Global.asax file.

      譯文:你能夠經過將路由對象添加到RouteTable類的靜態路由屬性中的方式將路由添加到應用程序中。路由屬性是一個爲應用程序存儲全部路由的路由對象。在MVC應用程序中,您一般不須要編寫代碼來添加路由。VS項目模板爲MVC包含了預先配置的URL路由。這些都是在MvcApplication類中定義的,被定義在Global.asac 文件中。

2.4 URL Patterns(URL模式)

A URL pattern can contain literal values and variable placeholders (referred to as URL parameters). The literals and placeholders are located in segments of the URL which are delimited by the slash (/) character.

譯文:URL模式可能包含文字值和變量佔位符(稱爲URL參數)。文字和佔位符位於URL的片斷中,由斜槓(/)字符分隔。

When a request is made, the URL is parsed into segments and placeholders, and the variable values are provided to the request handler. This process is similar to the way the data in query strings is parsed and passed to the request handler. In both cases variable information is included in the URL and passed to the handler in the form of key-value pairs. For query strings both the keys and the values are in the URL. For routes, the keys are the placeholder names defined in the URL pattern, and only the values are in the URL.

譯文:當發出請求時,URL被解析爲片斷和佔位符,且變量值被提供給請求處理程序。這個過程相似於查詢字符串中的數據被解析並傳遞給請求處理程序的方式。在這兩種狀況下,變量信息都包含在URL中,並以鍵值對的形式傳遞給處理程序。對於查詢字符串,鍵和值都在URL中。對於路由,鍵是URL模式中定義的佔位符名稱,在URL中僅僅是值。

In a URL pattern, you define placeholders by enclosing them in braces ( { and } ). You can define more than one placeholder in a segment, but they must be separated by a literal value. For example, {language}-{country}/{action} is a valid route pattern. However, {language}{country}/{action} is not a valid pattern, because there is no literal value or delimiter between the placeholders. Therefore, routing cannot determine where to separate the value for the language placeholder from the value for the country placeholder.

譯文:在URL模式中,經過將它們封裝在括號(以及)中來定義佔位符。您能夠在一個段中定義多個佔位符,可是必須用文字值分隔它們。例如,語言-國家/行動是一種有效的路線模式。然而,語言國家/action不是一個有效的模式,由於佔位符之間沒有文字值或分隔符。所以,路由不能決定將語言佔位符的值與國家佔位符的值分隔開。

The following table shows valid route patterns and examples of URL requests that match the patterns.

下表顯示了有效的路由模式和與模式匹配的URL請求示例。

 Typical URL Patterns in MVC Applications

譯文:MVC運用程序中的經典模式

 URL patterns for routes in MVC applications typically include {controller} and {action} placeholders.
譯文:在MVC運用程序中,路由URL模式一般包含控制器和動做佔位符。

When a request is received, it is routed to the UrlRoutingModule object and then to the MvcHandler HTTP handler. The MvcHandler HTTP handler determines which controller to invoke by adding the suffix "Controller" to the controller value in the URL to determine the type name of the controller that will handle the request. The action value in the URL determines which action method to call.

譯文:當接收到一個請求時,它被路由到UrlRoutingModule對象,而後發送到MvcHandler HTTP處理程序。MvcHandler HTTP處理程序經過向URL中的控制器值添加後綴「控制器」來肯定要調用哪一個控制器,以肯定控制器的類型名稱,該控制器將處理請求。URL中的操做值決定調用哪一個操做方法。

For example, a URL that includes the URL path /Products is mapped to a controller named ProductsController. The value in the action parameter is the name of the action method that is called. A URL that includes the URL path /Products/show would result in a call to the Showmethod of the ProductsController class.

譯文:例如,一個包含URL路徑  /產品 的URL映射到一個名爲ProductsController的控制器。action參數中的值是調用的操做方法的名稱。一個包含URL路徑   /產品/show  的URL會致使對ProductsController類的Showmethod的調用。

The following table shows the default URL patterns, and it shows examples of URL requests that are handled by the default routes.

譯文:下表顯示了默認的URL模式,它展現了由默認路由處理的URL請求的示例。

 

The route with the pattern {resource}.axd/{*pathInfo} is included to prevent requests for the Web resource files such as WebResource.axd or ScriptResource.axd from being passed to a controller.

For IIS 7.0, no file-name extension is needed. For IIS 6.0, you must add the .mvc file-name extension to the URL pattern, as in the following example:

譯文:帶有模式資源的路由axd/pathInfo,被用於防止Web資源文件的請求,例如WebResource,axd或ScriptResource傳遞到控制器。對於IIS 7.0,不須要任何文件名稱擴展。對於IIS 6.0,您必須添加.mvc文件擴展名到URL模式中,以下面的例子:

 

 如在VS2013使用MVC模板建立項目時,自動生成類RouteConfig.

2.5 Adding Routes to a Web Forms Application(添加路由到WebForm運用程序)

In a Web Forms application, you create routes by using the MapPageRoute(String, String, String) method of the RouteCollection class. The MapPageRoute method creates a Route object and adds it to the RouteCollection object. You specify properties for the Route object in parameters that you pass to the MapPageRoute method.

譯文:在Web Forms應用程序中,您可使用路由選擇類的MapPageRoute(字符串、字符串、字符串)方法建立路由。MapPageRoute方法建立一個路由對象並將其添加到RouteCollection對象。您能夠在傳遞給MapPageRoute方法的參數中指定路由對象的屬性。

Typically, you add routes in a method that is called from the handler for the Application_Start event in the Global.asax file. This approach makes sure that the routes are available when the application starts. It also enables you to call the method directly when you unit-test the application. If you want to call a method directly when you unit-test the application, the method that registers the routes must be static (Shared in Visual Basic) and must have a RouteCollection parameter.

譯文:一般地,在全局Global.asax文件中,您能夠在一個叫作Application_Start 方法裏添加路由。該方法確保當應用程序啓動時,路由是可使用的。它還使您能夠在對應用程序進行單元測試時直接調用該方法。若是您想在對應用程序進行單元測試時直接調用方法,那麼註冊路由的方法必須是靜態的(在Visual Basic中是共享的),而且必須具備一個路由參數。

The following example shows code from a Global.asax file that adds a Route object that defines two URL parameters named action and categoryName. URLs that have the specified pattern are directed to the physical page named Categories.aspx.

譯文:下面的示例展現了來自.Globalasax文件的代碼,該代碼添加了一個路由對象,該對象定義了兩個名爲action和類別名稱的URL參數。具備指定模式的url被定向到名爲分類.aspx的物理頁面。

protected void Application_Start(object sender, EventArgs e)
{
    RegisterRoutes(RouteTable.Routes);
}

public static void RegisterRoutes(RouteCollection routes)
{
    routes.MapPageRoute("",
        "Category/{action}/{categoryName}",
        "~/categoriespage.aspx");
}

2.6 Adding Routes to an MVC Application

 If you adopt the MVC convention of implementing controllers by creating classes that derive from the ControllerBase class and giving them names that end with "Controller", you do not need to manually add routes in an MVC application. The preconfigured routes will invoke the action methods that you implement in the controller classes.

譯文:若是您經過建立從控制器基類派生的類來實現控制器的MVC約定,並給它們以「控制器」結尾的名稱,那麼您就不須要在MVC應用程序中手動添加路由了。預配置的路由將調用您在控制器類中實現的操做方法。

If you want to add custom routes in an MVC application, you use the MapRoute(RouteCollection, String, String) method instead of the MapPageRoute(String, String, String) method.
譯文:若是您想在MVC應用程序中添加自定義路由,您可使用MapRoute(RouteCollection、String、String)方法,而不是MapPageRoute(字符串、字符串、字符串)方法。

The following example shows the code that creates default MVC routes in the Global.asax file, as defined in the Visual Studio project template for MVC applications.

 譯文:下面的例子展現了在全局中建立默認MVC路由的代碼。asax文件,正如在Visual Studio項目模板中定義的MVC應用程序。

public class MvcApplication : System.Web.HttpApplication { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( "Default",                                              // Route name 
            "{controller}/{action}/{id}",                           // URL with parameters 
            new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
 ); } protected void Application_Start() { RegisterRoutes(RouteTable.Routes); } }

2.7 Setting Default Values for URL Parameters(爲URL參數設置默認值)

When you define a route, you can assign a default value for a parameter. The default value is used if a value for that parameter is not included in the URL. You set default values for a route by assigning a dictionary object to the Defaults property of the Route class. The following example shows how to add a route that has default values, by using the MapPageRoute(String, String, String, Boolean, RouteValueDictionary) method.

譯文:當您定義一個路由時,您能夠爲一個參數指定一個默認值。若是該參數的值沒有包含在URL中,則使用默認值。經過將dictionary對象分配給route類的默認屬性,能夠爲路由設置默認值。下面的例子展現瞭如何經過使用MapPageRoute(字符串、字符串、字符串、布爾值、RouteValueDictionary)方法添加具備默認值的路由。

void Application_Start(object sender, EventArgs e) { RegisterRoutes(RouteTable.Routes); } public static void RegisterRoutes(RouteCollection routes) { routes.MapPageRoute("", "Category/{action}/{categoryName}", "~/categoriespage.aspx", true, new RouteValueDictionary {{"categoryName", "food"}, {"action", "show"}}); }

When ASP.NET routing handles a URL request, the route definition shown in the example (with default values of food for categoryName and showfor action) produces the results that are listed in the following table.

For MVC applications, overloads of the RouteCollectionExtensions.MapRoute method, such as MapRoute(RouteCollection, String, String, Object, Object), enable you to specify defaults.

2.8 Handling a Variable Number of Segments in a URL Pattern(在URL模式中處理可變數量的段)

Sometimes you have to handle URL requests that contain a variable number of URL segments. When you define a route, you can specify that if a URL has more segments than there are in the pattern, the extra segments are considered to be part of the last segment. To handle additional segments in this manner you mark the last parameter with an asterisk (*). This is referred to as a catch-all parameter. A route with a catch-all parameter will also match URLs that do not contain any values for the last parameter. The following example shows a route pattern that matches an unknown number of segments.

譯文:有時您必須處理包含一個可變數量的URL段的URL請求,其中。當您定義一個路由時,您能夠指定,若是一個URL的片斷比模式中有更多的段,那麼額外的段被認爲是最後一部分的一部分。要以這種方式處理額外的段,您能夠用星號(*)標記最後一個參數。這被稱爲一個籠統的參數。一個包含全部參數的路由也將匹配不包含最後一個參數的任何值的url。下面的示例展現了一個匹配未知數量的段的路由模式。

/ query / { queryname } { * queryvalues }

When ASP.NET routing handles a URL request, the route definition shown in the example produces the results that are listed in the following table.

譯文:當ASP.NET路由處理一個URL請求時,示例中所示的路由定義產生了下表中列出的結果。

2.9  Adding Constraints to Routes(爲路由添加約束)

In addition to matching a URL request to a route definition by the number of parameters in the URL, you can specify that values in the parameters meet certain constraints. If a URL contains values that are outside the constraints for a route, that route is not used to handle the request. You add constraints to make sure that the URL parameters contain values that will work in your application.

譯文:除了經過URL中參數的數量來匹配URL請求外,還能夠指定參數中的值知足特定的約束條件。若是一個URL包含的值超出了路由的約束,那麼該路由就不會被用於處理請求。您添加了一些約束,以確保URL參數包含在您的應用程序中工做的值。
Constraints are defined by using regular expressions or by using objects that implement the IRouteConstraint interface. When you add the route definition to the Routes collection, you add constraints by creating a RouteValueDictionary object that contains the verification test. The key in the dictionary identifies the parameter that the constraint applies to. The value in the dictionary can be either a string that represents a regular expression or an object that implements the IRouteConstraint interface.

譯文:約束是經過使用正則表達式或使用實現IRouteConstraint接口的對象來定義的。當將路由定義添加到路由集合時,經過建立一個包含驗證測試的RouteValueDictionary對象來添加約束。字典中的鍵標識約束應用到的參數。字典中的值能夠是表示正則表達式的字符串,也能夠是實現IRouteConstraint接口的對象。
If you provide a string, routing treats the string as a regular expression and checks whether the parameter value is valid by calling the IsMatch method of the Regex class. The regular expression is always treated as case-insensitive. For more information, see .NET Framework Regular Expressions.

譯文:若是您提供一個字符串,那麼路由將字符串做爲一個正則表達式來處理,並經過調用Regex類的IsMatch方法檢查參數值是否有效。正則表達式老是被視爲不區分大小寫的。要了解更多信息,請參閱。淨框架正則表達式。
If you provide an IRouteConstraint object, ASP.NET routing checks whether the parameter value is valid by calling the Match method of the IRouteConstraint object. The Match method returns a Boolean value that indicates whether the parameter value is valid.

譯文:若是你提供一個IRouteConstraint對象,ASP.NET 路由經過調用IRouteConstraint對象的匹配方法, 以此來檢查參數值是否有效。Match方法返回一個布爾值,該值表示參數值是否有效。
The following example shows how to use the MapPageRoute method to create a route that has constraints that limit what values can be included in the locale and year parameters. (In an MVC application, you would use the MapRoute method.)

譯文:下面的示例展現瞭如何使用MapPageRoute方法建立一條路徑,該路由限制了地區和年參數中能夠包含的值。(在MVC應用程序中,您將使用map路由方法。)

 

 1 public static void RegisterRoutes(RouteCollection routes)  2 {  3     routes.MapPageRoute("",  4         "Category/{action}/{categoryName}",  5         "~/categoriespage.aspx",  6         true,  7         new RouteValueDictionary  8             {{"categoryName", "food"}, {"action", "show"}},  9         new RouteValueDictionary 10             {{"locale", "[a-z]{2}-[a-z]{2}"},{"year", @"\d{4}"}} 11  ); 12 }

When routing handles a URL request, the route definition shown in the previous example produces the results that are listed in the following table.

 2.10 Scenarios When Routing Is Not Applied(不該用路由時的場景)

Under some circumstances, ASP.NET routing does not handle a request even when is enabled for the Web site. This section describes some scenarios in which routing does not handle the request.

譯文:在某些狀況下,即便在Web站點啓用時,ASP.NET 路由也不處理請求。本部分描述了一些場景,其中路由不處理請求。

A Physical File is Found that Matches the URL Pattern(找到與URL模式匹配的物理文件)

By default, routing does not handle requests that map to an existing physical file on the Web server. For example, a request for http://server/application/Products/Beverages/Coffee.aspx is not handled by routing if a physical file exists at Products/Beverages/Coffee.aspx. Routing does not handle the request even if it matches a defined pattern, such as {controller}/{action}/{id}.

譯文:默認狀況下,路由不處理映射到Web服務器上現有物理文件的請求。例如,若是存在 Products/Beverages/Coffee.aspx.物理文件,請求http://server/application/Products/Beverages/Coffee.aspx 不被路由處理。即便它與已定義的模式相匹配,路由不處理請求,例如控制器/動做/id。
If you want routing to handle all requests, even requests that point to files, you can override the default behavior by setting the RouteExistingFiles property of the RouteCollection object to true. When you set this value to true, all requests that match a defined pattern are handled by routing.

譯文:若是您想要路由處理全部請求,甚至指向文件的請求,您能夠經過設置RouteCollection對象的屬性RouteExistingFiles爲true,  以此來覆蓋默認值。當您將這個值設置爲true時,匹配定義模式的全部請求都由路由處理。

Routing Is Explicitly Disabled for a URL Pattern(爲URL模式顯式禁用路由)

You can also specify that routing should not handle certain URL requests. You prevent routing from handling certain requests by defining a route and specifying that the StopRoutingHandler class should be used to handle that pattern. When a request is handled by a StopRoutingHandler object, the StopRoutingHandler object blocks any additional processing of the request as a route. Instead, the request is processed as an ASP.NET page, Web service, or other ASP.NET endpoint. You can use the RouteCollection.Ignore method  

譯文:您還能夠指定路由不該該處理某些URL請求。經過定義一條路由,並指定StopRoutingHandler類應該用於處理該模式,從而避免了處理某些請求的路由。當一個StopRoutingHandler對象處理請求時,StopRoutingHandler對象會阻塞請求做爲路由的任何附加處理。相反,請求是做爲ASP.NET 頁面來處理的,網絡頁面,Web服務,或其餘ASP.NET端點。您可使用 RouteCollection.Ignore方法。

1 public static void RegisterRoutes(RouteCollection routes) 2 { 3   routes.Ignore("{resource}.axd/{*pathInfo}"); 4 }

2.11 How URLs Are Matched to Routes(url如何與路由匹配)

When routing handles URL requests, it tries to match the URL of the request to a route. Matching a URL request to a route depends on all the following conditions:

譯文:當路由處理URL請求時,它嘗試將請求的URL與路由匹配。將URL請求匹配到路由取決於如下條件:

  • The route patterns that you have defined or the default route patterns, if any, that are included in your project type. 

  • 譯文:您已經定義的路由模式或默認的路由模式,若是有的話,它們包含在您的項目類型中。
  • The order in which you added them to the Routes collection.
  •  譯文:您將它們添加到路由集合的順序。
  • Any default values that you have provided for a route.
  • 譯文:您爲某個路由提供的任何默認值。
  • Any constraints that you have provided for a route.

  • 譯文:您爲路線所提供的任何約束。
  • Whether you have defined routing to handle requests that match a physical file.

  • 譯文:是否認義了路由來處理與物理文件匹配的請求。

For example, suppose that you add routes with the following patterns:

譯文:例如,假設您添加了如下模式:
   Route 1 is set to {controller}/{action}/{id}

   譯文: 路徑1設置爲{controller}/{action}/{id}
   Route 2 is set to products/show/{id}

  譯文:路線2設置爲 products/show/{id}
Route 2 will never handle a request because Route 1 is evaluated first, and it will always match requests that could also work for Route 2. A request for http://server/application/products/show/bikes seems to match Route 2 more closely, but it is handled by Route 1 with the following values:
controller is products.
action is show.
id is bikes.

譯文:

路由2永遠不會處理請求,由於路由1首先被匹配,它老是匹配可能在2號路徑上工做的請求。請求http://server/application/products/show/bikes彷佛比賽路線2更緊密,但它是由路線1如下值:

控制器products.

行動是show.

id是bikes.

Default values are used if a parameter is missing from the request. Therefore, they can cause a route to match a request that you did not expect. For example, suppose that you add routes with the following patterns:
Route 1: {report}/{year}/{month}, with default values for year and month.
Route 2: {report}/{year}, with a default value for year.
Route 2 will never handle a request. Route 1 might be intended for a monthly report, and Route 2 might be intended for an annual report. However, the default values in Route 1 mean that it will match any request that could also work for Route 2.

譯文:

若是請求中缺乏一個參數,則使用默認值。所以,它們能夠致使一條匹配您沒有預料到的請求的路由。例如,假設您添加了如下模式:

路線1:報告/年/月,年和月默認值。

路線2:報告/年,年默認值。

路由2永遠不會處理請求。第1條多是針對每個月報告的,而路由2多是針對年度報告的。可是,路由1中的默認值意味着它將匹配任何可能用於路由2的請求。

You can avoid ambiguity in the patterns by including constants, such as annual/{report}/{year} and monthly/{report}/{year}/{month}.
If a URL does not match any Route object that is defined in the RouteTable collection, ASP.NET routing does not process the request. Instead, processing is passed to an ASP.NET page, Web service, or other ASP.NET endpoint.

譯文:您能夠經過包含常量來避免模式中的歧義,例如 annual/{report}/{year} and monthly/{report}/{year}/{month}。

若是URL不匹配在RouteTable集合中定義的任何路由對象,ASP.NET路由不處理請求。相反,處理被傳遞給一個ASP.NET Page ,Web服務,或其餘ASP.NET端點。

2.12 路由二義性

只在同一個解決方案中,存在兩個以及以上相同控制器下的相同action,當URL請求時,會出現二義性。

二義性Demo目錄結構

RouteConfig.cs

 1 using System;  2 using System.Collections.Generic;  3 using System.Linq;  4 using System.Web;  5 using System.Web.Mvc;  6 using System.Web.Routing;  7 
 8 namespace MVCDemo  9 { 10     public class RouteConfig 11  { 12         public static void RegisterRoutes(RouteCollection routes) 13  { 14             routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 15 
16  routes.MapRoute( 17                 name: "Default", 18                 url: "{controller}/{action}/{id}", 19                 defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 20                 
21  ); 22  } 23  } 24 } 25                 
View Code

/Controllers/RouteDemo

 1 using System;  2 using System.Collections.Generic;  3 using System.Linq;  4 using System.Web;  5 using System.Web.Mvc;  6 
 7 namespace MVCDemo.Controllers  8 {  9     public class RouteDemoController : Controller 10  { 11         //
12         // GET: /RouteDemo/
13         public ActionResult Index() 14  { 15             return View(); 16  } 17  } 18 }
View Code

/Controllers/NewFolder1/RouteDemo

 1 using System;  2 using System.Collections.Generic;  3 using System.Linq;  4 using System.Web;  5 using System.Web.Mvc;  6 
 7 namespace MVCDemo.Controllers.NewFolder1  8 {  9     public class RouteDemoController : Controller 10  { 11         //
12         // GET: /RouteDemo/
13         public ActionResult Index() 14  { 15             return Content("路由二義性測試"); 16  } 17  } 18 }
View Code

測試結果

3 路由概述(特性路由)

 特性路由是在ASP.NET MVC 5中新增的,傳統路由ASP.NET MVC 1中就有了。

 從內容上來看,特性路由的內容與傳統路由差很少,一樣有路由URL、路由值、控制器路由、路由約束和路由默認值等。鑑於篇幅限制,在這裏就簡單的概述一下,不做詳細論述,後期有時間或者有朋友須要,再論述。

 定義:特性路由就是將路由URL定義在控制器上或控制器內的方法上,而不像傳統路由將路由URL定義在RouteConfig.cs中。對好比下

 

3 路由生成URL

   路由兩個重要職責:匹配傳入的URL請求和構造與特定路由對應的URL,歸納之匹配URL和構造URL。在生成URL時,生成URL的情趣應該首先與選擇用來生成URL的路由相匹配,這樣路由就能夠在處理傳入或傳出的URL時成爲完整的雙向系統。原則上,開發人員應該提供一組路由值,以便路由系統從中選中第一個可以匹配URL的路由。

 3.1 URL生成的高層系概述

  路由的核心是一個很是簡單的算法,該算法基於一個由RouteCollection類和RouteBase類組成的簡單抽象對象。能夠採用多種方法來生成URL,但這些方法都以調用RouteCollection.GetVirtualPath的一個重載方法而結束。RouteCollection.GetVirtulPath方法公有兩個重載版本,下面的代碼展現它們的方法簽名:

1  public VirtualPathData GetVirtualPath(RequestContext requestContex,RouteValueDictionary values) 2 
3  public  VirtualPathData GetVirtualPath(RequestContext requestContex,string name,RouteValueDictionary values)

 第一個重載版本接受當前的RequestContext,以及由用戶指定的路由值(字典)。

(1)路由集合經過RouteBase.GetVirtualPath方法遍歷每一個路由並訪問:「能夠生成給定參數的URL嗎」,這個過程相似於在路由與傳入請求匹配時所運用的匹配邏輯。

(2)若是一個路由能夠應答上面的問題(即匹配),那麼它就會返回一個包含了URL的VirTualPathData實例以及其餘匹配的信息。不然,它就返回空值,路由機制移向列表中的下一個路由。

第二個重載接受三個參數,其中第二個參數是路由名稱。在路由集合中路由名稱是惟一的,也就是說,沒有兩個不一樣的路由具備相同的名稱。當指定了路由名稱時,路由集合就不須要循環遍歷每一個路由,相反,它能夠當即找到指定名稱的路由,並移向上面的步驟(2)。若是找到的路由不能匹配指定的參數,該方法就會返回空值,而且再也不匹配其餘路由。

  3.2  URL生成詳解

  (1)開發人員調用像Html.ActionLink或Url.Action之類的方法,這些方法反過來再調用RouteCollection.GetVirtualPath方法,並向它傳遞一個RequestContext對象、一個包含值的字典以及用來選擇生成URL的路由名稱(可選參數)。

 (2)路由機制查看要求的路由參數(即沒有提供路由參數的默認值),並確保提供的路由值字典爲每個要求的參數提供一個值,不然,URL生成程序就會當即中止,並返回空值。

 (3)一些路由可能包含沒有對應路由參數的默認值。如路由可能爲category鍵提供默認值「pastries」,可是cateory不是路由URL的一個參數,這種狀況下,若是用戶傳入的路由值字典爲category提供了一個值,那麼該值必須匹配category的默認值。

 (4)而後路由系統應用路由約束。

(5)路由匹配成!如今能夠經過查看每個路由參數,並嘗試利用字典中的對應值填充相應參數,進而生成URL。

能夠歸納爲以下流程圖:

 

4 路由綁定到操做

 在這一章節,主要分析URL綁定到控制器操做的底層細節,分析底層原理,理解ASP.NET請求管道。注意,目前路由不只僅只是ASP.NET MVC的一個特性了,它已經超過這個範圍,如ASP.NET Dynamic Data。路由既不包括MVC的內部知識,也不依賴於MVC。

 4.1 高層次請求的路由管道

  當ASP.NET 處理請求時,路由管道主要由如下幾步組成:

   (1)UrlRoutingModule嘗試使用在RouteTable中註冊的路由匹配當前請求。

   (2)若是RouteTable中有一個路由成功匹配,路由模塊就會從匹配成功的路由中獲取IRouteHandler接口對象。

   (3)路由模塊調用IRouteHandler接口的GetHandler方法,並返回用來處理請求的IHttpHandler對象。

   (4)調用HTTP處理程序中的ProcessRequest方法,而後把要處理的請求傳遞給它

   (5)在ASP.NET MVC中,IRouteHandler是MvcRouteHandler類的一個實例,MvcRouteHandler轉而返回一個實現了IHttpHandler接口的MvcHandler對象。返回的MvcHandler對象主要用來實例化控制器,並調        用該實例化的控制器上的操做方法。

4.2 路由數據

    調用GetRouteData方法會返回RouteData的一個實例。RouteData中包含了關於匹配請求的路由信息。

    如URL:{Controller}/{action}/{id}。當請求/albums/list/123傳入時,該路由就會嘗試匹配傳入的請求,若是匹配成功,它就建立一個字典,其中包含了從URL中解析出的信息。確切地講,路由還會向Values字典中爲URL中的每一個路由參數添加一個鍵;對於傳統路由{Controller}/{action}/{id},Values字典中應該至少包含三個鍵,分別是Controller,action和id,若是傳入的URL是對/albums/list/123的請求,路由就會解析該請求的URL,併爲字典的鍵提供值。本例中,字典中「Controller」鍵的值爲albums,"action"鍵的值爲「list」,"id"鍵的值是「123」;對於特性路由MVC使用DataTokens字典來存儲更精確的信息,而不是操做名稱字符串。具體來講,它包含一個操做描述符列表,這些描述符直接指向路由匹配時可能使用的操做方法。對於控制器級別的特性路由,列表中將有不止一個操做。在整個MVC中都有用到的RequestContext的RouteData屬性保存着外界路由值。

5 路由調試

   使用RouteDebugger調試,啓用RouteDebugger後,它會用一個DebuggerRouteHandler替換全部路由處理程序,DebugRouteHandler截獲全部傳入的請求,並查詢路由表中的每個路由,以便在頁面底部顯示路由的診斷數據和參數。爲使用RouteDebugger,只需在VS的Package Manager Console窗口中使用NuGet安裝便可,命令Install-Package routedebugger.。RouteDebugger包在添加Route Debugger程序集的同時。也在web.config文件的appSettings節點中添加一個設置,用來開啓或禁用路由調試。

<add key="RouteDebugger:Enable" value="true'>

 只要啓用RouteDebugger,它就顯示從(在地址欄中)當前請求URL中提取的路由數據。如此,能夠在地址欄中輸入各類URL,並查看輸入的URL能與哪一個路由匹配,在頁面底部,它還會展現一個包含應用程序定義的所用路由列表,這樣能夠查看定義的哪一個路由可以與當前URL相匹配。

安裝教程以下:

視圖=>其餘窗口=>程序包管理控制檯

在窗口中輸入:Install-Package routedebugger

或者也可使用NuGet很方便的安裝RouteDebugger,在項目上面右鍵-"Manage NuGet Packages"-"Online"輸入"RouteDebugger"而後"Install".

固然, 你也能夠本身下載RouteDebugger.dll, 引用到web項目中, 而後手動在web.config中加入

<add key="RouteDebugger:Enabled" value="true" />

測試結果

RouteConfig.cs

 1 using System;  2 using System.Collections.Generic;  3 using System.Linq;  4 using System.Web;  5 using System.Web.Mvc;  6 using System.Web.Routing;  7 
 8 namespace MVCDemo  9 { 10     public class RouteConfig 11  { 12         public static void RegisterRoutes(RouteCollection routes) 13  { 14             routes.MapMvcAttributeRoutes();// 15 
16             routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 17 
18  routes.MapRoute( 19                 name: "Default", 20                 url: "{controller}/{action}/{id}", 21                 defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 22  ); 23  } 24  } 25 }

RouteDemoController

 1 using System;  2 using System.Collections.Generic;  3 using System.Linq;  4 using System.Web;  5 using System.Web.Mvc;  6 
 7 namespace MVCDemo.Controllers  8 {  9     public class RouteDemoController : Controller 10  { 11         //
12         // GET: /RouteDemo/
13         public ActionResult Index() 14  { 15             return View(); 16  } 17  } 18 }

Index

1 @inherits System.Web.Mvc.WebViewPage 2 
3 <h2>RouteDebugger調試</h2>

 

6 與路由相關的關鍵命名空間和類

 6.1  路由涉及的命名空間

 6.2 Class Reference( 路由涉及到的關鍵類)

 

7 總結

 因爲篇幅有限,路由章節就寫到這,固然,還有不少內容沒寫,如路由配置文件、路由安全設置、自定義路由約束等,留給讀者朋友們去研究吧。

8 參考文獻

 【01】https://msdn.microsoft.com/en-us/library/cc668201.aspx#setting_default_values_for_url_parameters

【02】http://www.cnblogs.com/willick/p/3343105.html

【03】https://msdn.microsoft.com/zh-cn/library/cc668201(v=vs.100).aspx

【04】Professional Asp.net MVC 5

【05】http://www.cnblogs.com/liangxiaofeng/p/5620033.html

【06】https://msdn.microsoft.com/en-us/library/cc668177.aspx

【07】https://msdn.microsoft.com/en-us/library/dd535620.aspx

【08】https://msdn.microsoft.com/en-us/library/cc668176.aspx

【09】https://msdn.microsoft.com/en-us/library/dd329551.aspx

【10】https://msdn.microsoft.com/en-us/library/system.web.routing.route.aspx

【11】https://msdn.microsoft.com/en-us/library/system.web.routing.pageroutehandler.aspx

【12】https://msdn.microsoft.com/en-us/library/system.web.mvc.mvcroutehandler.aspx

【13】https://msdn.microsoft.com/en-us/library/system.web.ui.page.routedata.aspx

【14】https://msdn.microsoft.com/en-us/library/bb398900.aspx

【15】https://msdn.microsoft.com/en-us/library/ee941656.aspx

 

9   版權

 

  • 感謝您的閱讀,如有不足之處,歡迎指教,共同窗習、共同進步。
  • 博主網址:http://www.cnblogs.com/wangjiming/。
  • 極少部分文章利用讀書、參考、引用、抄襲、複製和粘貼等多種方式整合而成的,大部分爲原創。
  • 如您喜歡,麻煩推薦一下;如您有新想法,歡迎提出,郵箱:2016177728@qq.com。
  • 能夠轉載該博客,但必須著名博客來源。
相關文章
相關標籤/搜索