ASP.NET路由[ASP.NET Routing]

ASP.NET路由[ASP.NET Routing]

  ASP.NET路由容許你在使用URL時沒必要匹配到網站中具體的文件,由於這個URL沒必要匹配到一個文件,你使用了描述用戶行爲且更容易被用戶理解的URL。ios

  ASP.NET MVC框架和ASP.NET動態數據(Dynamic Data)擴展路由爲MVC應用和動態數據應用增長了特點。git

  在不使用路由的ASP.NET應用中,一個新的請求會被映射到一個物理文件並由該文件處理這個請求,例如一個.aspx文件。例如,以下請求http://server/application/Products.aspx?id=4會題映射到一個包含代碼和標籤來向瀏覽器渲染響應的Products.aspx文件。Web頁面人員使用id=4的查詢字符來肯定顯示的內容。web

  使用ASP.NET路由,你能夠定義映射請求-處理程序(request-handler)文件的URL模式,但不必在將這些文件的名字包含在這個URL中。除此以外,你還能夠經過在URL模式中使用佔位符來向請求處理程序傳輸變量數據,而沒必要使用查詢字符串。正則表達式

  例如,以下請求 http://server/application/Products/show/beverages,路由分析器會向頁面處理器傳入Products,show,beverages這些值。在這個例子中,若是使用server/application/{area}/{action}/{category}URL模式定義路由,頁面處理器將會收到一個字典集合,這個集合中包含如下鍵值對,area:Products,action:show,category:beverages。若是是在一個不被URL路由管理的請求中,/Products/show/beverages片段將會被看成應用中的一個文件路徑解釋執行。編程

1、      路由[Routes]

  路由是被處理程序映射的URL模式。處理程序能夠是一個物理文件,例如Web Form應用中的.aspx文件。處理也能夠是處理請求的類,例如MVC應用中的控制器。爲了定義一個路由,你須要建立一個Route類的實例來指定URL模式,處理程序和可選的路由名稱。瀏覽器

  你須要給RouteTable類的Routes靜態屬性添加Route對象來爲應用添加路由。Routes屬性是一個RouteCollection對象,其中存放着應用中全部路由規則。安全

  你一般沒有必要爲MVC應用編寫代碼添加來添加路由規則。Visual Studio的MVC項目模板包含了預配置的URL路由規則。他們定義在MvcApplication類,這個類在Global.asax文件中。服務器

2、      URL模式[URL Patterns]

  一個URL模式能夠包含字面值(literal)和可變的佔位符(參考URL參數)。這些字面值和佔位符在URL片段中經過斜線(/)字符來分開和定位。網絡

  當一個請求到達,這個URL被解析成片段和佔位符,這些變量會提供給請求處理器。這個過程和將數據經過查詢字符串(query strings)中解析和傳輸至請求處理器很相似。這兩種狀況下變量信息都會包含在URL中並傳處處理程序的鍵值對的表單中。對於查詢字符串而言,全部鍵(keys)和值(values)都包含在URL中。對於路由方式,全部鍵就是在URL模式中定義的佔位符名稱,只有值包含中URL中。mvc

  在一個URL模式中,你定義的佔位符被大括號包裹起來({and})。你能夠在一個片段中定義多個佔位符,可是它們必須被字面值分隔開。例如,{language}-{country}/{action}就是一個合法的路由模式。然而{language}{country}/{action}不是一個合法的路由模式,由於它們的佔位符之間缺乏字面值或分隔符。所以,路由沒法肯定language和country佔位符的值是何處分隔。

  下表給出了合法的路由模式,以及其各自能正確匹配的URL請求。

路由定義

匹配URL示例

{controller}/{action}/{id}

/Products/show/beverages

{table}/Details.aspx

/Products/Details.aspx

blog/{action}/{entry}

/blog/show/123

{reporttype}/{year}/{month}/{day}

/sales/2008/1/5

{locale}/{action}

/US/show

{language}-{country}/{action}

/en-US/show

MVC應用中標準的URL模式[Typical URL Patterns in MVC Applications]

  在MVC應用中,路由標準的URL模式包含{controller}和 {action}佔位符。

  當接收到一個請求時,它先被髮送到UrlRoutingModule對象,再發送到MvcHandler HTTP處理程序。MvcHandler HTTP處理程序肯定須要執行的控制器,經過給URL中的controller值添加」Controller」後綴從而肯定將處理本次請求的控制器類型名稱。URL中的action值肯定調用的處理方法。

  例如,URL路徑 /Products會被映射成ProductsController控制器。action參數的值是被調用的處理方法的名稱。URL路徑/Products/show的映射結果將會是調用類ProductsController 的方法Show。

  下表給出了默認的URL模式和它們能處理的URL請求示例。

默認URL模式

匹配URL示例

{controller}/{action}/{id}

http://server/application/Products/show/beverages

{resource}.axd/{*pathInfo}

http://server/application/WebResource.axd?d=...

  路由使用模式 {resource}.axd/{*pathInfo} 來阻止對網絡文件的請求,例如WebReource.axd,ScriptResource.axd被傳遞給一個控制器。

  對於IIS7.0,能夠不用擴展名。對於IIS6.0,你必須將擴展名.mvc添加到URL模式,以下所示:{controller}.mvc/{action}/{id}

3、      爲Web Forms應用程序添加路由[Add Routes to a Web Forms Application]

  在Web Form應用中,你可使用類RouteCollection的方法MapPageRoute(String, String, String) 建立路由。方法MapPageRoute建立Route對象並將其添加RouteCollection對象中。你須要爲Route對象在參數在指定一些屬性,用來傳給方法MapPageRoute

  一般狀況下,你在方法中添加的路由會被Global.asax文件中Application_Start 方法處理器調用。這種方法確保了這些路由在應用程序啓動時能夠正常調用。它也容許你在爲應用程序作單元測試時可直接調用該方法。當你在作單元測試時若是想要直接調用一個方法,該方法在註冊時就必須是靜態(Visual Basic中Shared)且有一個RouteCollection參數。

  下例中演示了Global.asax文件中添加一個Route對象,該對象定義了action和categoryName兩個參數。URL中還定義了一個被定向到名爲Categories.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");
}
View Code

4、      爲MVC應用程序添加路由[Adding Routes to an MVC Application]

  在MVC應用程序中,若是你採用MVC實現控制器的約定,即派生自類ControllerBase且以「Controller」結尾命名,那麼你根本不須要搬運添加路由。預配置的路由將會執行你實現的控制器類中的處理方法。

  若是你但願在MVC應用程序中添加自定義的路由,你可使用方法MapRoute(RouteCollection, String, String) 來取代方法MapPageRoute(String, String, String)

  下面示例中演示在Global.asax文件中建立默認MVC路由的代碼,便是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);
    }
}
View Code

5、      爲URL參數設置默認值[Setting Default Values for URL Parameters]

  當你定義一個路由時,你能夠爲參數指定一個默認值。若是一個參數的值不在URL中,則使用默認值。給路由設置默認值時是給類Route的屬性Defaults指定一個字典對象。下例演示瞭如何使用方法MapPageRoute(String, String, String, Boolean, 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"}});
}
View Code

  下圖中演示了ASP.NET路由處理URL請求,路由定義(categoryName的默認值爲food,action默認爲show)和解析結果:

URL

Parameter values

/Category

action = "show" (default value)

categoryName = "food" (default value)

/Category/add

action = "add"

categoryName = "food" (default value)

/Category/add/beverages

action = "add"

categoryName= "beverages"

  對於MVC應用程序,方法RouteCollectionExtensions.MapRoute的重載版本,如MapRoute(RouteCollection, String, String, Object, Object),容許你指定默認值。

6、      URL模式中處理可變數量片段[Handling a Variable Number of Segments in a URL Pattern]

  有時候你必須處理包含可變個數的URL片段的URL請求。當你定義一個路由時,你能夠指定當一個URL擁有比模式中還要多的片段時,額外的片段會被看成最後一個片段對待。你須要爲最後一個參數添加一個星號(*)來用這種方式處理額外的片段。這被稱做全匹配(catch-all)參數。包含全匹配參數也將匹配最後參數不帶任何值的URL。下例展現一個能夠匹配沒法肯定片段長度的路由模式。

  query/{queryname}/{*queryvalues}

  下圖中演示了ASP.NET路由處理URL請求,路由定義和解析結果。

URL

Parameter values

/query/select/bikes/onsale

queryname = "select"

queryvalues = "bikes/onsale"

/query/select/bikes

queryname = "select"

queryvalues = "bikes"

/query/select

queryname = "select"

queryvalues = Empty string

7、      爲路由添加約束[Adding Constraints to Routes]

  路由模式中除了定義了可匹配URL請求的參數個數,還能夠指定這些參數的值須要知足的某些約束。若是一個URL中的參數值不符合一個路由的約束,那麼此路由不會處理該請求。你添加的約束條件是爲了確保URL參數中包含的值能在你的應用程序中工做。

  約束條件是用正則表達式或實現了接口IRouteConstraint的對象來定義。當你將一條路由添加進Routes 集合時,你能夠添加包含驗證測試的對象RouteValueDictionary約束條件。字典中的鍵惟一標識符合約束條件的參數。字典中的值既能夠是符合正則表達式的字符串,也能夠是實現接口IRouteConstraint的對象。

  若是你提供一個字符串,路由會將它看成符合正則表達式的值,並調用Regex類的IsMatch()方法檢查該參數值是否符合規則。正則表達式老是不區分大小寫檢查。

  若是你提供了一個IRouteConstraint對象,ASP.NET路由調用IRouteConstraint對象的Match()方法來檢查參數值是否合法。Match()方法返回布爾值來代表參數值是否合法。

  下例中演示如何利用方法MapPageRoute 添加一條路由,併爲參數locale和year添加約束。(MVC應用程序中,使用方法MapRoute。)

public static void RegisterRoutes(RouteCollection routes)
{
    routes.MapPageRoute("",
        "Category/{action}/{categoryName}",
        "~/categoriespage.aspx",
        true,
        new RouteValueDictionary 
            {{"categoryName", "food"}, {"action", "show"}},
        new RouteValueDictionary 
            {{"locale", "[a-z]{2}-[a-z]{2}"},{"year", @"\d{4}"}}
       );
}
View Code

  當路由處理URL請求時,例子中路由的定義和解析後的結果以下表所示:

URL

Result

/US

No match. Both locale and year are required.

/US/08

No match. The constraint on year requires 4 digits.

/US/2008

locale = "US"

year = "2008"

8、      路由不起做用的狀況[Scenarios When Routing Is Not Applied]

  在某些狀況下,ASP.NET路由即便可用也不會處理請求。這節將介紹幾種路由不會處理請求的狀況。

URL模式匹配一個有效的物理文件[A Physical File is Found that Matches the URL Pattern]

  默認狀況下,路由不會處理請求時,將其映射到Web服務器上一個已存在的物理文件。例如,若是存在一個物理文件Products/Beverages/Coffee.aspx,路由就不會處理請求http://server/application/Products/Beverages/Coffee.aspx。路由即便以下定義{controller}/{action}/{id},也能匹配該請求,它也不會處理該請求。

  若是你但願路由能處理全部請求,即便請求指向一個文件,你能夠經過設置對象RouteCollection的屬性RouteExistingFilestrue來重寫默認行爲。當你將這個值設置爲true則全部與定義路由模式匹配的請求都會被路由處理。

顯式禁用路由[Routing Is Explicitly Disabled for a URL Pattern]

  你也能夠指明路由不處理某些URL請求。定義一個路由並指明由類StopRoutingHandler處理該模式,以阻止路由處理某些請求。當一個請求被StopRoutingHandler對象處理時,StopRoutingHandler對象塊會爲請求添加一些額外的信息。相反,這個請求會被看成一個ASP.NET頁面、Web服務或是其餘ASP.NET終端處理。你可使用方法RouteCollection.Ignore(MVC應用程序中RouteCollectionExtensions.IgnoreRoute)來建立使用類 StopRoutingHandler的路由。下面演示如何阻止對WebResource.axd文件的請求。

public static void RegisterRoutes(RouteCollection routes)
{
  routes.Ignore("{resource}.axd/{*pathInfo}");
}
View Code

  URL是如何被路由匹配的[How URLs Are Matched to Routes]

  當路由開始處理URL請求時,它爲嘗試着將請求匹配到一條路由規則上。一條路由規則可否匹配URL請求取決與如下條件:

    • 在你的項目中是否包含自定義的路由規則或者默認路由。
    • 集合Routes中添加路由規則的順序。
    • 爲路由規則添加的默認值。
    • 爲路由規則添加的約束。
    • 是否認義了匹配對物理文件請求的路由。

  爲了不不合適的路由處理了請求,在定義路由規則時必定要考慮全部這些條件。集合 RoutesRoute對象出現的順序也應仔細思考。路由集合中從第一項到最後一項依次嘗試的路由匹配。當有一個匹配成功,再也不對後續路由嘗試匹配。一般,添加路由時應先添加最具體的,最後添加最不明確的規則。

  例如你添加了以下路由規則:

    •   路由規則1,{controller}/{action}/{id}
    •   路由規則2, products/show/{id}

  路由2毫不會處理請求,由於路由1會最早嘗試匹配,而且與路由2匹配的請求在它上面也老是能夠工做。例如請求http://server/application/products/show/bikes看起來好像和路由2更匹配,可是它會被路由1解析,解析結果以下:

    •   controller is products.
    •   action is show.
    •   id is bikes.

  當請求的參數缺乏時,默認值就能起做用。然而,它們可能會匹配到並不是你所願的請求。例如,假如添加以下兩條路由規則:

    •   路由1:{report}/{year}/{month},year,month帶有默認值。
    •   路由2:{report}/{year},year有默認值。

  路由2將絕無處理請求的機會。路由1但願能按月份匹配,而路由2則但願是按年度。可是,路由1中的默認值會讓全部匹配路由2的請求在路由1中也能工做。

  你能夠在路由中包含常量來避免這種歧義,例如annual/{report}/{year}和monthly/{report}/{year}/{month}。

  若是一個URL不能匹配到在RouteTable集合中的任何一個Route對象,ASP.NET路由將不會處理該請求。

9、      從路由建立URL[Creating URLs from Routes]

  若是你想要建立一個連接到你站點頁面的超連接,你可使用URL模式編程建立符合路由的URL。當你修改了路由模式,URL會自動匹配到新的模式上。

10、      在路由頁面訪問URL參數[Accessing URL Parameters in a Routed Page]

參見:https://msdn.microsoft.com/en-us/library/dd535620.aspx

https://msdn.microsoft.com/en-us/library/dd394711.aspx

11、      配置路由環境[Configuration Settings for Routing]

  ASP.NET中,要讓應用程序支持路由功能,須要添加以下配置:

<configuration>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <!-- more -->
    </modules>
  </system.webServer>
</configuration>
View Code

  當runAllManagedModulesForAllRequests爲true時,以下URLhttp://mysite/myapp/home,即便URL中沒有.aspx,.mvc或者其餘擴展名,該請求也能到達ASP.NET。

  然而,IIS7的更新致使沒必要添加配置項runAllManagedModulesForAllRequests,由於它原本就支持ASP.NET路由功能。

  若是你的站點運行在IIS7且IIS已更新,你就沒必要設置該配置項爲true。事實上,並不推薦設置它,由於它爲全部請求增長了沒必要要的操做。若是設置該配置爲true,全部請求,包括.htm,.jpg和其餘靜態文件都會經過ASP.NET請求通道。

  默認runAllManagedModulesForAllRequests爲false。若是網站配置文件中沒有明確將其設置爲true,而你又在未安裝SP1的Windows 7,不包含必要更新的IIS7中運行你的網站。 結果就是,你會看到路由不會工做的錯誤提示。若是路由中存在一些問題,你能夠試試下面的方法:

    •   將Windows 7更新到SP1,由於它添加了IIS7的更新。
    •   安裝微軟件在先前文章中的描述的更新。
    •   在Web.Config文件中設置runAllManagedModulesForAllRequests爲true。注意這會添加一些額外開銷。

12、      ASP.NET路由與安全性[ASP.NET Routing and Security]

  受權規則可應用於單獨映射的路由URL或同時映射的路由URL和物理URL。例如,受權規則能夠聲明全部用戶均可以訪問以開頭Category的URL,可是隻有管理員才能訪問Categories.aspx頁面。若是路由URL模式contoso.com/Category/{controller}/{action} 映射到物理地址contoso.com/Categoriespage.aspx,你只能爲路由地址添加受權規則,當用一個路由地址請求過以後,全部用戶都被容許可訪問Categoriespage.aspx。然而,當使用物理地址請求以後,只有管理纔有權限訪問。

  默認狀況下,受權規則應用於路由地址和物理地址。

十3、      ASP.NET Web Form和路由安全性[ASP.NET Web Forms and Route Security]

  在ASP.NET Web窗體應用程序中,你不該該將站點的安全性全寄託在路由受權規則,由於它們可能留下一些未保護處理的物理地址。

十4、      ASP.NET MVC和路由安全性[ASP.NET MVC and Route Security]

  你不能使用路由或web.config文件保證MVC應用程序的安全性。惟一能保證MVC應用安全的作法是給全部控制器應用特性 AuthorizeAttribute ,並在登陸和註冊的方法(action)上應用特性AllowAnonymousAttribute 。

  擴展請查看:http://blogs.msdn.com/b/rickandy/archive/2012/03/23/securing-your-asp-net-mvc-4-app-and-the-new-allowanonymous-attribute.aspx

十5、      參考類[Class Reference]

Class

Description

Route

Represents a route in a Web Forms or MVC application.

DynamicDataRoute

Represents a route in a Dynamic Data application.

RouteBase

Serves as the base class for all classes that represent an ASP.NET route.

RouteTable

Stores the routes for an application.

RouteCollection

Provides methods that enable you to manage a collection of routes.

RouteCollectionExtensions

Provides additional methods that enable you to manage a collection of routes in MVC applications.

RouteData

Contains the values for a requested route.

RequestContext

Contains information about the HTTP request that corresponds to a route.

StopRoutingHandler

Provides a way to specify that ASP.NET routing should not handle requests for a URL pattern.

PageRouteHandler

Provides a way to define routes for Web Forms applications.

RouteValueDictionary

Provides a way to store route ConstraintsDefaults, and DataTokensobjects.

VirtualPathData

Provides a way to generate URLs from route information.

十6、      ASP.NET路由VS URL重寫[ASP.NET Routing versus URL Rewriting]

  ASP.NET路由與URL重寫不一樣。URL重寫方式處理到達的請求時,先修改其URL再將請求發送至Web頁面。例如,一個應用程序中可能使用URL重寫將/Products/Widgets/修改成/Products.aspx?id=4。同時,URL重寫的特色是沒有基於你的模式建立URL的API。使用URL重寫,若是你須要個性URL規則,你不得不手動更新全部相關聯的超連接。

  使用ASP.NET路由,在處理到達的請求時URL不會發生變化,由於路由功能可能從URL中提取值。當你須要建立一個URL時,給一個方法傳入參數值就能爲你生成URL。修改URL規則,只須要調整一個地方,你在應用程序中建立的全部連接都會自動使用新規則。

 

  源地址:https://msdn.microsoft.com/en-us/library/cc668201.aspx?cs-save-lang=1&cs-lang=csharp#aspnet_routing_versus_url_rewriting

相關文章
相關標籤/搜索