ASP.NET 路由使您可以使用不必映射到网站中特定文件的 URL。 由于该 URL 不必映射到文件,因此可以使用对用户操作进行描述因而更易于被用户理解的 URL。

ASP.NET MVC 框架和 ASP.NET 动态数据对路由进行扩展,以提供仅在 MVC 应用程序和动态数据应用程序中使用的功能。 有关 ASP.NET MVC 的更多信息,请参见 ASP.NET MVC。 有关动态数据的更多信息,请参见ASP.NET 动态数据内容映射

在不使用路由的 ASP.NET 应用程序中,对 URL 的传入请求通常映射到处理该请求的物理文件,如 .aspx 文件。例如,对 http://server/application/Products.aspx?id=4 的请求映射到名为 Products.aspx 的文件,该文件包含代码和标记用于呈现对浏览器的响应。 网页使用查询字符串值 id=4 来确定要显示的内容类型。

在 ASP.NET 路由中,可以定义 URL 模式,这些模式映射到请求处理程序文件但是不必在 URL 中包含这些文件的名称。 另外,可以在 URL 模式中包含占位符,以便无需查询字符串,即可将变量数据传递到请求处理程序。

例如,在请求 http://server/application/Products/show/beverages 时,路由分析器可以将值Products、show 和 beverages 传递给页处理程序。 在此示例中,如果路由是使用 URL 模式server/application/{area}/{action}/{category} 定义的,则页处理程序将收到一个字典集合,在该集合中,与键 area 关联的值为 Products,键 action 的值为 show,键 category 的值为 beverages。 在不由 URL 路由管理的请求中,/Products/show/beverages 片断将被解释为应用程序中一个文件的路径。

本主题包含以下各节:

“路由”是映射到处理程序的 URL 模式。 处理程序可以是物理文件,例如 Web 窗体应用程序中的 .aspx 文件。 处理程序还可以是处理请求的类,例如 MVC 应用程序中的控制器。 若要定义路由,可以通过指定 URL 模式、处理程序和(可选)路由名称,创建 Route 类的一个实例。

通过将 Route 对象添加到 RouteTable 类的静态 Routes 属性,向应用程序中添加路由。 Routes 属性是一个存储应用程序的所有路由的 RouteCollection 对象。

通常不必编写代码来在 MVC 应用程序中添加路由。 MVC 的 Visual Studio 项目模板包含预先配置的 URL 路由。 它们是在 MvcApplication 类中定义的,该类是在 Global.asax 文件中定义的。

URL 模式可以包含文本值和变量占位符(也称为“URL 参数”)。 文本和占位符位于由斜杠 (/) 字符分隔的 URL 段中。

当生成请求时,URL 分析为段和占位符,变量值提供给请求处理程序。 此过程类似于分析查询字符串中的数据并将该数据传递给请求处理程序的方法。 在两种情况下,变量信息都包括在 URL 中并以键值对的形式传递给处理程序。 对于查询字符串,键和值都位于 URL 中。 对于路由,键是在 URL 模式中定义的占位符名称,只有值位于 URL 中。

在 URL 模式中,可以通过用大括号({ 和 })括住占位符来定义占位符。 可以在一个段中定义多个占位符,但必须用一个文本值分隔开。 例如,{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 模式

MVC 应用程序中用于路由的 URL 模式通常包括 {controller} 和 {action} 占位符。

当收到请求时,会将其路由到 UrlRoutingModule 对象,然后路由到 MvcHandler HTTP 处理程序。MvcHandler HTTP 处理程序通过向 URL 中的控制器值添加后缀“Controller”以确定将处理请求的控制器的类型名称,来确定要调用的控制器。 URL 中的操作值确定要调用的操作方法。

例如,包含 URL 路径 /Products 的 URL 映射到名为 ProductsController 的控制器。 action 参数中的值是调用的操作方法的名称。 包含 URL 路径 /Products/show 的 URL 将导致调用 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} 的路由,以避免对 Web 资源文件(例如 WebResource.axd 或 ScriptResource.axd)的请求传递给控制器。

对于 IIS 7.0,不需要文件扩展名。 对于 IIS 6.0,必须向 URL 模式添加 .mvc 文件扩展名,如下面的示例所示:

 
 
{controller}.mvc/{action}/{id}

在 Web 窗体应用程序中,通过使用 RouteCollection 类的 MapPageRoute(String, String, String) 方法来创建路由。 MapPageRoute 方法创建 Route 对象,并将其添加到 RouteCollection 对象。 可以在传递到MapPageRoute 方法的参数中指定 Route 对象的属性。

通常情况下,您在 Global.asax 文件中 Application_Start 事件的处理程序调用的方法中添加路由。 该方法可确保应用程序启动时路由可用。 还使您能够在对应用程序进行单元测试时直接调用方法。 如果您想在对应用程序进行单元测试时直接调用一个注册路由的方法,则该方法必须是静态的(Visual Basic 中的Shared),并且必须具有一个 RouteCollection 参数。

下面的示例演示从 Global.asax 文件中添加一个 Route 对象的代码,该对象定义了名为 action 和categoryName 的两个 URL 参数。 具有指定模式的 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");
}

如果通过创建派生自 ControllerBase 类的类并赋予它们以“Controller”结尾的名称来采纳实现控制器的 MVC 惯例,则不需要在 MVC 应用程序中手动添加路由。 预先配置的路由将调用您在控制器类中实现的操作方法。

如果想要在 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);
}
}

定义路由时可以为参数分配一个默认值。 如果 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"}});
}

ASP.NET 路由处理 URL 请求时,在示例中演示的路由定义(使用针对 categoryName 的 food 的默认值和针对 action 的 show 的默认值)得到下表列出的结果。

 

URL

参数值

/Category

action = "show"(默认值)

categoryName = "food"(默认值)

/Category/add

action = "add"

categoryName = "food"(默认值)

/Category/add/beverages

action = "add"

categoryName= "beverages"

对于 MVC 应用程序,通过 RouteCollectionExtensions.MapRoute 方法的重载(例如MapRoute(RouteCollection, String, String, Object, Object))可以指定默认值。

有时您需要处理包含可变数量的 URL 段的 URL 请求。 定义路由时,可以指定 URL 是否具有比模式中更多的段,是否将额外的段视为最后一个段的一部分。 若要以此方式处理额外的段,可以用星号 (*) 标记最后一个参数。 该参数称为“可用于放置各种信息的”参数。 具有全部捕捉参数的路由也将与那些不包含最后一个参数的任意值的 URL 相匹配。 下面的示例演示一个与未知数量的段匹配的路由模式。

query/{queryname}/{*queryvalues}

ASP.NET 路由处理 URL 请求时,在示例中演示的路由定义得到下表列出的结果。

 

URL

参数值

/query/select/bikes/onsale

queryname = "select"

queryvalues = "bikes/onsale"

/query/select/bikes

queryname = "select"

queryvalues = "bikes"

/query/select

queryname = "select"

queryvalues = Empty string

除了按照 URL 中的参数数量将 URL 请求匹配到路由定义中,还可以指定参数中的值满足特定约束。 如果一个 URL 包含路由的约束以外的值,则该路由不用于处理请求。 添加约束以确保 URL 参数包含将在应用程序中起作用的值。

约束是通过使用正则表达式或使用实现 IRouteConstraint 接口的对象来定义的。 将路由定义添加到 Routes集合时,同时也通过创建一个包含验证测试的 RouteValueDictionary 对象添加了约束。 字典中的关键字标识约束适用的参数。 字典中的值可以是表示正则表达式的字符串,也可以是实现 IRouteConstraint 接口的对象。

提供字符串后,路由将视字符串为正则表达式,并通过调用 Regex 类的 IsMatch 方法检查参数值是否有效。总是将正则表达式视为不区分大小写。 有关更多信息,请参见 .NET Framework 正则表达式

提供 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}"}}
);
}

路由处理 URL 请求时,在上一示例中演示的路由定义生成下表列出的结果。

 

URL

结果

/US

无匹配。 locale 和 year 都是必需的。

/US/08

无匹配。 对 year 的约束需要 4 个数字。

/US/2008

locale = "US"

year = "2008"

在某些情况下,即使为网站启用了请求,ASP.NET 路由也不处理请求。 本节介绍路由不处理请求的一些情况。

找到匹配 URL 模式的物理文件

默认情况下,路由不处理映射到 Web 服务器上现有物理文件的请求。 例如,如果 Products/Beverages/Coffee.aspx 上存在物理文件,则路由不处理对http://server/application/Products/Beverages/Coffee.aspx 的请求。 即使匹配一个定义的模式(例如 {controller}/{action}/{id}),路由也不处理该请求。

如果希望路由处理所有请求(包括指向文件的请求),可以通过将 RouteCollection 对象的 RouteExistingFiles属性设置为 true 来重写默认行为。 将该值设置为 true 后,与定义的模式匹配的所有请求都将由路由处理。

为 URL 模式显式禁用路由

还可以指定路由不应处理某些 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}");
}

路由在处理 URL 请求时,还尝试将请求的 URL 与路由匹配。 将 URL 请求与路由匹配取决于以下所有条件:

  • 包括在项目类型中的已经定义的路由模式或默认路由模式(如果有的话)。

  • 将路由添加到 Routes 集合中的顺序。

  • 已经提供给路由的所有默认值。

  • 已经提供给路由的任意约束。

  • 是否定义路由来处理匹配物理文件的请求。

为避免错误的处理程序处理请求,必须在定义路由时考虑以上所有条件。 出现在 Routes 集合中的 Route 对象的顺序是很重要的。 路由将在集合的整个路由过程中一直尝试匹配。 当匹配发生时,无法计算更多的路由。 通常,按从路由定义的具体性递减的顺序将路由添加到 Routes 属性。

例如,假定您使用以下模式添加路由:

  • 路由 1 设置为 {controller}/{action}/{id}

  • 路由 2 设置为 products/show/{id}

路由 2 将不再处理请求,这是因为首先计算路由 1,路由 1 始终匹配同样适用于路由 2 的请求。 对http://server/application/products/show/bikes 的请求似乎能更好地匹配路由 2,但它是由路由 1 使用下列值处理的:

  • controller 为 products。

  • action 为 show。

  • id 为 bikes。

如果请求缺少参数,则会使用默认值。 因此,可能导致路由匹配意外的请求。 例如,假定您使用以下模式添加路由:

  • 路由 1:{report}/{year}/{month},对于 year 和 month 使用默认值。

  • 路由 2:{report}/{year},对于 year 使用默认值。

路由 2 将永远不处理请求。 路由 1 可能用于月度报表,而路由 2 可能用于年度报表。 但是,路由 1 中的默认值意味着将匹配同时适用于路由 2 的所有请求。

可以通过在模式中包括例如 annual/{report}/{year} 和 monthly/{report}/{year}/{month} 的常量来避免二义性。

如果 URL 与在 RouteTable 集合中定义的任何 Route 对象都不匹配,ASP.NET 路由将不处理请求。 相反,会将处理传递给 ASP.NET 页、Web 服务或其他 ASP.NET 终结点。

如果想要在站点中创建页的超链接,可以使用 URL 模式通过编程方式来创建对应于路由的 URL。 当更改模式时,将自动生成匹配新模式的 URL。 有关如何在代码或标记中生成 URL 的信息,请参见如何:通过路由构造 URL

在已路由的页请求的处理程序中,可以使用代码或标记访问 URL 占位符中传递的值。 有关更多信息,请参见如何:在路由页面中访问 URL 参数

对于 MVC 应用程序,MVC 框架自动处理 URL 占位符中传递的值。 有关更多信息,请参见在 ASP.NET MVC 应用程序中传递数据

授权规则可以仅应用于路由 URL,也可以同时应用于路由 URL 和它映射到的物理 URL。 例如,授权规则可以指定所有用户可以访问以 Category 开头的 URL,但是只有管理员可以访问 Categories.aspx 页。 如果路由 URL 模式 contoso.com/Category/{controller}/{action} 映射到物理 URLcontoso.com/Categoriespage.aspx,且您仅将授权规则应用于路由 URL,则当使用路由 URL 请求 Categoriespage.aspx 时允许所有用户访问 Categoriespage.aspx。 但是,当使用物理 URL 请求它时,只有管理员可以访问它。

默认情况下,授权规则同时应用于路由 URL 和物理 URL。 有关更多信息,请参见PageRouteHandler.CheckPhysicalUrlAccess 属性。

下表列出了 ASP.NET 路由的关键服务器类。

 

说明

Route

表示 Web 窗体或 MVC 应用程序中的路由。

DynamicDataRoute

表示动态数据应用程序中的路由。

RouteBase

用作表示 ASP.NET 路由的所有类的基类。

RouteTable

存储应用程序的路由。

RouteCollection

提供使您可以管理路由集合的方法。

RouteCollectionExtensions

提供使您可以在 MVC 应用程序中管理路由集合的其他方法。

RouteData

包含所请求路由的值。

RequestContext

包含有关对应于路由的 HTTP 请求的信息。

StopRoutingHandler

提供一种方式,来指定 ASP.NET 路由不应处理 URL 模式的请求。

PageRouteHandler

提供用于定义 Web 窗体应用程序的路由的方法。

RouteValueDictionary

提供用于存储路由 ConstraintsDefaults 和 DataTokens 对象的方法。

VirtualPathData

提供用于从路由信息生成 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 模式,请在某位置更改该模式,您在应用程序中创建的基于该模式的所有链接将自动使用新模式。

ASP.NET路由的更多相关文章

  1. ASP.NET路由模型解析

    大家好,我又来吹牛逼了 ~-_-~ 转载请注明出处:来自吹牛逼之<ASP.NET路由模型解析> 背景:很多人知道Asp.Net中路由怎么用的,却不知道路由模型内部的运行原理,今天我就给大家 ...

  2. ASP.NET路由[ASP.NET Routing]

    ASP.NET路由[ASP.NET Routing] ASP.NET路由允许你在使用URL时不必匹配到网站中具体的文件,因为这个URL不必匹配到一个文件,你使用了描述用户行为且更容易被用户理解的URL ...

  3. ASP.NET路由系统实现原理:HttpHandler的动态映射

    我们知道一个请求最终通过一个具体的HttpHandler进行处理,而我们熟悉的用于表示一个Web页面的Page对象就是一个HttpHandler,被用于处理基于某个.aspx文件的请求.我们可以通过H ...

  4. ASP.NET 路由

    URL 模式可以包含文本值和变量占位符(也称为“URL 参数”).  文本和占位符位于由斜杠 (/) 字符分隔的 URL 段中. 当生成请求时,URL 分析为段和占位符,变量值提供给请求处理程序.  ...

  5. 剖析Asp.Net路由系统

    对于Asp.Net Web Forms应用来说,请求的Url都是对应一个具体的物理文件(http://xxx.com/default.aspx).这样的Url与具体物理文件紧密绑定在一起,带来了诸多方 ...

  6. ASP.NET Web API 框架研究 ASP.NET 路由

    ASP.NET Web API 如果采用Web Host方式来寄宿,在请求进入Web API 消息处理管道之前,就会用ASP.NET 自身的路由系统根据注册的路由表,解析出当前请求的HttpContr ...

  7. 类型:.net;问题:ASP.NET路由;结果:ASP.NET 路由 .NET Framework 4

    ASP.NET 路由 .NET Framework 4   更新:2007 年 11 月 ASP.NET 路由使您可以使用不必映射到网站中特定文件的 URL.由于 URL 不必映射到文件,所以可以在 ...

  8. URL重写及ASP.NET路由、Http处理模块、程序等

    这段时间在学习ASP.NET路由.HTTP处理等内容,了解了一些,但又未完全弄懂,似是而非,不管如何,作一总结,供日后借鉴和修改. 一.IIS6和IIS7经典模式和集成模式 在IIS6及IIS7经典模 ...

  9. 我的IIS7.5竟然不支持ASP.NET路由

    MVC模式下那些友好,屏蔽具体物理文件的URL让我眼馋,咱也想在WEB FORM项目用上一用. 按照指引,添加global.asax,写上路由代码什么的: <%@ Application Lan ...

随机推荐

  1. C#连接Oracle数据库基本类

    C#用来连接oracle数据库的基本类: using System; using System.Collections.Generic; using System.Linq; using System ...

  2. 说一说Servlet 的生命周期

    答:servlet 有良好的生存期的定义, 包括加载和实例化. 初始化. 处理请求以及服务结束.这个生存期由 javax.servlet.Servlet 接口的 init,service 和 dest ...

  3. MySqlQueryList

    //辅助查询列表,或实例 public class MySqlQueryList { #region List<T> ToList<T>(string sql, params ...

  4. FOREIGN KEY相关

    在添加外键的时候可以在最后通过ON指定行为和三个参数,来表示操作主表数据之后外表的变化 比如若是删除主表之后的变化,就可以 ON DELETE + 三个参数 --删除department表中相关数据行 ...

  5. bzoj 1196: [HNOI2006]公路修建问题 二分+并查集

    题目链接 1196: [HNOI2006]公路修建问题 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1576  Solved: 909[Submit ...

  6. ASP.NET MVC5 学习笔记-4 OWIN和Katana

    1. Owin OWIN全名:Open Web Interface for .NET. 它是一个说明,而非一个框架,该声明用来实现Web服务器和框架的松耦合.它提供了模块化.轻量级和便携的设计.类似N ...

  7. java json的处理

    maven依赖 <dependencies> <dependency> <groupId>com.alibaba</groupId> <artif ...

  8. 我的Fedora环境

    Fedora现在也更新到了第20个版本,只是在15+以后的版本,大多数操作,都是大同小异的,也不必特意去关注版本号,只有对应到具体的软件,可能会因为库的版本,有或多或少的区别. 之前每次都喜欢按照一些 ...

  9. BZOJ 1088 扫雷Mine (递推)

    题解:如果确定了第一排前两个数,那么剩下的数是唯一确定的,所以只要分情况讨论即可. #include <cstdio> #include <cstring> int n,a[1 ...

  10. Spring 面试复习

    1   singleton 和 prototype singleton作用域:当把一个Bean定义设置为singleton作用域是,Spring IoC容器中只会存在一个共享的Bean实例,并且所有对 ...