ASP.NET路由[ASP.NET Routing]


ASP.NET路由[ASP.NET Routing]

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

  ASP.NET MVC框架和ASP.NET動態數據(Dynamic Data)擴展路由為MVC應用和動態數據應用增加了特色。

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

  使用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片斷將會被當作應用中的一個文件路徑解釋執行。

一、      路由[Routes]

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

  你需要給RouteTable類的Routes靜態屬性添加Route對象來為應用添加路由。Routes屬性是一個RouteCollection對象,其中存放着應用中所有路由規則。

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

二、      URL模式[URL Patterns]

  一個URL模式可以包含字面值(literal)和可變的占位符(參考URL參數)。這些字面值和占位符在URL片斷中通過斜線(/)字符來分開和定位。

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

  在一個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}

三、      為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

四、      為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

五、      為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),允許你指定默認值。

六、      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

七、      為路由添加約束[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"

八、      路由不起作用的情況[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路由將不會處理該請求。

九、      從路由創建URL[Creating URLs from Routes]

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

十、      在路由頁面訪問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

十一、      配置路由環境[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。注意這會添加一些額外開銷。

十二、      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。然而,當使用物理地址請求之后,只有管理才有權限訪問。

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

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

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

十四、      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

十五、      參考類[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.

十六、      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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM