类型:.net;问题:ASP.NET路由;结果:ASP.NET 路由 .NET Framework 4
ASP.NET 路由
更新:2007 年 11 月
ASP.NET 路由使您可以使用不必映射到网站中特定文件的 URL。由于 URL 不必映射到文件,所以可以在 Web 应用程序中使用 URL,这些 URL 是描述性的用户操作,因此更易于被用户理解。
在一个不使用路由的 ASP.NET 应用程序中,对 URL 的传入请求通常映射到磁盘上的物理文件,如 .aspx 文件。例如,对http://server/application/Products.aspx?id=4 的请求映射到名为 Products.aspx 的文件,该文件包含代码和标记用于呈现对浏览器的响应。网页使用 id=4 的查询字符串值来决定显示的内容类型,但是该值对用户可能意义不大。
在 ASP.NET 路由中,您可以定义 URL 模式,该模式包含在处理 URL 请求时使用的值的占位符。在运行时,应用程序名称后面的 URL 部分根据您所定义的 URL 模式分析为离散值。例如,在请求 http://server/application/Products/show/beverages 时,路由分析器可以将值 Products、show 和 beverages 传递给请求的处理程序。相反,在一个不由 URL 路由管理的请求中,/Products/show/beverages 片断将被解释为应用程序中一个文件的路径。
还可以使用 URL 模式通过编程方式来创建对应于路由的 URL。这使您能够集中逻辑用于创建 ASP.NET 应用程序中的超链接。
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 模式,请在某位置更改该模式,您在应用程序中创建的基于该模式的所有链接将自动使用新模式。
定义的 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} |
/zh-cn/show |
{language}-{country}/{action} |
/zh-cn/show |
通常情况下,您在 Global.asax 文件中 Application_Start 事件的处理程序调用的方法中添加路由。该方法可确保应用程序启动时路由可用。还使您能够在对应用程序进行单元测试时直接调用方法。如果您想在对应用程序进行单元测试时直接调用一个注册路由的方法,则该方法必须是静态的(Visual Basic 中的 Shared),并且必须具有一个 RouteCollection 参数。
您可以通过将路由添加到 RouteTable 类的静态 Routes 属性来添加路由。Routes 属性是一个 RouteCollection 对象,存储 ASP.NET 应用程序的所有路由。下面的示例演示从 Global.asax 文件中添加一个 Route 对象的代码,该对象定义了名为 action 和categoryName 的两个 URL 参数。
定义路由时可以为参数分配一个默认值。如果 URL 没有包括该参数的值,则会使用默认值。通过将字典分配给 Route 类的 Defaults属性,可以设置路由的默认值。下面的示例演示一个包含默认值的路由。
void Application_Start(object sender, EventArgs e)
{
RegisterRoutes(RouteTable.Routes);
} public static void RegisterRoutes(RouteCollection routes)
{
routes.Add(new Route
(
"Category/{action}/{categoryName}"
new CategoryRouteHandler()
)
{
Defaults = 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" |
有时您需要处理包含可变数量的 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 对象添加了约束。然后将此对象分配给 Constraints 属性。字典中的关键字标识约束适用的参数。字典中的值可以是表示正则表达式的字符串,也可以是实现 IRouteConstraint 接口的对象。
提供字符串后,路由将视字符串为正则表达式,并通过调用 Regex 类的 IsMatch 方法检查参数值是否有效。总是将正则表达式视为不区分大小写。有关更多信息,请参见 .NET Framework 正则表达式。
提供 IRouteConstraint 对象后,ASP.NET 路由将通过调用 IRouteConstraint 对象的 Match 方法检查参数值是否有效。Match 方法返回一个布尔值,该值指示参数值是否有效。
下面的示例演示限制在 locale 和 year 参数中包含的值的约束。
void Application_Start(object sender, EventArgs e)
{
RegisterRoutes(RouteTable.Routes);
} public static void RegisterRoutes(RouteCollection routes)
{
routes.Add(new Route
(
"{locale}/{year}"
, new ReportRouteHandler()
)
{
Constraints = new RouteValueDictionary
{{"locale", "[a-z]{2}-[a-z]{2}"},{year, @"\d{4}"}}
});
}
路由处理 URL 请求时,在上一示例中演示的路由定义生成下表列出的结果。
URL |
结果 |
---|---|
/zh-CN |
无匹配。locale 和 year 都是必需的。 |
/zh-CN/08 |
无匹配。对 year 的约束需要 4 个数字。 |
/zh-CN/2008 |
locale = "zh-CN" year = "2008" |
默认情况下,路由不处理映射到 Web 服务器上现有物理文件的请求。例如,如果 Products/Beverages/Coffee.aspx 上存在物理文件,则路由不处理对 http://server/application/Products/Beverages/Coffee.aspx 的请求。即使匹配一个定义的模式,例如{controller}/{action}/{id},路由也不处理该请求。
如果希望路由处理所有请求(包括指向文件的请求),可以通过将 RouteCollection 对象的 RouteExistingFiles 属性设置为 true 来覆盖默认行为。将该值设置为 true 后,与定义的模式匹配的所有请求都将由路由处理。
还可以指定路由不应处理某些 URL 请求。通过定义路由并指定应使用 StopRoutingHandler 类来处理该模式,来阻止路由处理某些特定请求。当 StopRoutingHandler 对象处理请求时,StopRoutingHandler 对象会阻止以任何其他方式将该请求处理为路由。相反,会将该请求处理为 ASP.NET 页、Web 服务或其他 ASP.NET 终结点。例如,您可以添加以下路由定义来阻止路由处理 WebResource.axd 文件的请求。
路由在处理 URL 请求时,还尝试将请求的 URL 与路由匹配。将 URL 请求与路由匹配取决于以下所有条件:
包括在项目类型中的已经定义的路由模式或默认路由模式(如果有的话)。
将路由添加到 Routes 集合中的顺序。
已经提供给路由的所有默认值。
已经提供给路由的任意约束。
是否定义路由来处理匹配物理文件的请求。
为避免错误的处理程序处理请求,必须在定义路由时考虑以上所有条件。出现在 Routes 集合中的 Route 对象的顺序是很重要的。路由将在集合的整个路由过程中一直尝试匹配。当匹配发生时,无法计算更多的路由。通常,按从路由定义的具体性递减的顺序将路由添加到 Routes 属性。
例如,假定您使用以下模式添加路由:
路由 1:{controller}/{action}/{id}
路由 2:products/show/{id}
由于先计算路由 1,并将一直匹配也适用于路由 2 的请求,所以路由 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。通过将参数值作为字典传递给 RouteCollection 对象的 GetVirtualPath方法来创建 URL。GetVirtualPath 方法在 RouteCollection 对象中查找与字典中的参数匹配第一个路由。匹配路由用于生成 URL。下面的示例演示路由定义。
public static void RegisterRoutes(RouteCollection routes)
{
routes.Add(new Route
(
"Category/{action}/{categoryName}"
new CategoryRouteHandler()
)
{
Defaults = new RouteValueDictionary {{"categoryName", "food"},
{"action", "show"}}
}
);
}
下面的示例演示一个基于路由创建 URL 的控件。
Dim urlParameters As RouteValueDictionary urlParameters = New RouteValueDictionary(New With {.categoryName = "beverages", _
.action = "summarize"})
HyperLink1.NavigateUrl = RouteTable.Routes.GetVirtualPath _
(context, urlParameters).VirtualPath
HyperLink1.NavigateUrl = RouteTable.Routes.GetVirtualPath
(context,
new RouteValueDictionary {
{ "categoryName", "beverages" },
{"action", "summarize" }}
).VirtualPath;
运行此代码时,HyperLink1 控件将包含 NavigateUrl 属性中的值“Category/summarize/beverages”。
从路由创建 URL 时,可以通过包括路由的名称来指定使用哪个路由创建 URL。有关更多信息,请参见如何:通过路由构造 URL。。
社区附加资源
类型:.net;问题:ASP.NET路由;结果:ASP.NET 路由 .NET Framework 4的更多相关文章
- .NET/ASP.NET Routing路由(深入解析路由系统架构原理)
阅读目录: 1.开篇介绍 2.ASP.NET Routing 路由对象模型的位置 3.ASP.NET Routing 路由对象模型的入口 4.ASP.NET Routing 路由对象模型的内部结构 4 ...
- .NET/ASP.NET Routing路由(深入解析路由系统架构原理)http://wangqingpei557.blog.51cto.com/1009349/1312422
阅读目录: 1.开篇介绍 2.ASP.NET Routing 路由对象模型的位置 3.ASP.NET Routing 路由对象模型的入口 4.ASP.NET Routing 路由对象模型的内部结构 4 ...
- NET/ASP.NET Routing路由(深入解析路由系统架构原理)(转载)
NET/ASP.NET Routing路由(深入解析路由系统架构原理) 阅读目录: 1.开篇介绍 2.ASP.NET Routing 路由对象模型的位置 3.ASP.NET Routing 路由对象模 ...
- 一、ASP.NET Routing路由(深入解析路由系统架构原理)
阅读目录: 1.开篇介绍 2.ASP.NET Routing 路由对象模型的位置 3.ASP.NET Routing 路由对象模型的入口 4.ASP.NET Routing 路由对象模型的内部结构 4 ...
- 白话ASP.NET MVC之一:Url 路由
好久没有写关于ASP.NET MVC的东西了,虽然<ASP.NET MVC4框架揭秘>已经完完整整的看完一遍,但是感觉和一锅粥差不多,没什么可写的,因为我自己不理解,也就写不出来.现在开始 ...
- ASP.NET MVC5高级编程 之 路由
每个ASP.NET MVC应用程序都需要路由来定义自己处理请求的方式.路由是MVC应用程序的入口点.路由的核心工作是将一个请求映射到一个操作 路由主要有两种用途: 匹配传入的请求(该请求不匹配服务器文 ...
- 给Asp.Net MVC及WebApi添加路由优先级
一.为什么需要路由优先级 大家都知道我们在Asp.Net MVC项目或WebApi项目中注册路由是没有优先级的,当项目比较大.或有多个区域.或多个Web项目.或采用插件式框架开发时,我们的路由注册很可 ...
- 【ASP.NET Web API教程】4.1 ASP.NET Web API中的路由
原文:[ASP.NET Web API教程]4.1 ASP.NET Web API中的路由 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本博客文章,请先看前面的内容. ...
- Asp.Net MVC 进阶篇:路由匹配 实现博客路径 和文章路径
Asp.Net MVC 进阶篇:路由匹配 实现博客路径 和文章路径 我们要实现 通过路由 匹配出 博客地址 和博客文章地址 例如下面的这两个地址 //http://www.cnblogs.com/ma ...
- asp.net core mvc 中间件之路由
asp.net core mvc 中间件之路由 路由中间件 首先看路由中间件的源码 先用httpContext实例化一个路由上下文,然后把中间件接收到的路由添加到路由上下文的路由集合 然后把路由上下文 ...
随机推荐
- VMWARE TOOLS安装出错:THE PATH IS NOT A VALID PATH TO THE 3.11.0.12-GENERIC KERNEL HEADERS
VMWARE TOOLS安装提示THE PATH IS NOT A VALID PATH TO THE GENERIC KERNEL HEADERS I solved this problem, I ...
- VC 写注册表
BOOL Running() { HKEY hKey; LPCTSTR strRegPath = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion ...
- QT 实现拖放功能
1. 文档拖放 获取文件名 mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #i ...
- enter回车---焦点切换
$(function(){ $('.enter').bind('keydown',function(e){ var inputs = $('.enter_cash'); var key = e.whi ...
- 阿里云分布式缓存OCS与DB之间的数据一致性
[分布式系统的数据一致性问题] OCS概要介绍 据AlertSite网络分析公司表示,Facebook的响应时间在2010年平均为1秒钟,到2011年中期已提高到了0.73秒.对比来看,响应时间占 ...
- (链接)xcode7,ios9 部分兼容设置
xcode7,ios9 部分兼容设置 http://www.cnblogs.com/loganv/p/4647833.html
- hzau 1203 One Stroke
1203: One Stroke Time Limit: 2 Sec Memory Limit: 1280 MBSubmit: 264 Solved: 56[Submit][Status][Web ...
- Spring MVC数据绑定大全 .
刚开始用spring mvc 做web开发时,经常会不知道如何合适绑定页面数据.用惯struts2的朋友更认为spring mvc 绑定数据不如struts2方便(本人最开始也是这么认为),经过一段时 ...
- c++primer 第四章编程练习答案
4.13.1 #include<iostream> struct students { ]; ]; char grade; int age; }; int main() { using n ...
- GEF入门实例_总结_03_显示菜单和工具栏
一.前言 本文承接上一节: GEF入门实例_总结_02_新建初始RCP空项目 这一节,我们来给我们的插件加上菜单. 二.基础知识 1.action bar.menubar.coolbar 含义 a ...