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

ASP.NET 路由

.NET Framework 4

更新: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 重写

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 参数”)。分析 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 参数。

C#

VB

protected 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()
    ));
}

为路由参数设置默认值

定义路由时可以为参数分配一个默认值。如果 URL 没有包括该参数的值,则会使用默认值。通过将字典分配给 Route 类的 Defaults属性,可以设置路由的默认值。下面的示例演示一个包含默认值的路由。

C#

VB

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 参数中包含的值的约束。

C#

VB

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 文件的请求。

C#

VB

public static void RegisterRoutes(RouteCollection routes)
{
  routes.Add(new Route("{resource}.axd/{*pathInfo}", new StopRouteHandler()));
}

URL 如何与路由匹配

路由在处理 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 时可以使用路由来生成 URL。通过将参数值作为字典传递给 RouteCollection 对象的 GetVirtualPath方法来创建 URL。GetVirtualPath 方法在 RouteCollection 对象中查找与字典中的参数匹配第一个路由。匹配路由用于生成 URL。下面的示例演示路由定义。

C#

VB

public static void RegisterRoutes(RouteCollection routes)
{
  routes.Add(new Route
  (
     "Category/{action}/{categoryName}"
          new CategoryRouteHandler()
  )
    {
       Defaults = new RouteValueDictionary {{"categoryName", "food"},
           {"action", "show"}}
     }
  );
}

下面的示例演示一个基于路由创建 URL 的控件。

VB

Dim urlParameters As RouteValueDictionary

urlParameters = New RouteValueDictionary(New With {.categoryName = "beverages", _
        .action = "summarize"})
HyperLink1.NavigateUrl = RouteTable.Routes.GetVirtualPath _
    (context, urlParameters).VirtualPath

C#

HyperLink1.NavigateUrl = RouteTable.Routes.GetVirtualPath
  (context,
  new RouteValueDictionary {
    { "categoryName", "beverages" },
    {"action", "summarize" }}
  ).VirtualPath;

运行此代码时,HyperLink1 控件将包含 NavigateUrl 属性中的值“Category/summarize/beverages”。

从路由创建 URL 时,可以通过包括路由的名称来指定使用哪个路由创建 URL。有关更多信息,请参见如何:通过路由构造 URL。

请参见

概念

理解 ASP.NET 基础结构

社区附加资源

添加

时间: 2024-11-11 04:25:14

类型:.net;问题:ASP.NET路由;结果:ASP.NET 路由 .NET Framework 4的相关文章

.NET/ASP.NET Routing路由(深入解析路由系统架构原理)

出处:http://www.cnblogs.com/wangiqngpei557/ 阅读目录: 1.开篇介绍 2.ASP.NET Routing 路由对象模型的位置 3.ASP.NET Routing 路由对象模型的入口 4.ASP.NET Routing 路由对象模型的内部结构 4.1UrlRoutingModule 对象内部结构 4.2RouteBase.Route.RouteCollection.RouteTable 路由核心对象模型 4.3RouteValueDictionary.Rou

【转】.NET/ASP.NET Routing路由(深入解析路由系统架构原理)

阅读目录: 1.开篇介绍 2.ASP.NET Routing 路由对象模型的位置 3.ASP.NET Routing 路由对象模型的入口 4.ASP.NET Routing 路由对象模型的内部结构 4.1]UrlRoutingModule 对象内部结构 4.2]RouteBase.Route.RouteCollection.RouteTable 路由核心对象模型 4.3]RouteValueDictionary.RouteData.RequestContext 路由数据对象模型 4.4]IRou

NET/ASP.NET Routing路由(深入解析路由系统架构原理)(转载)

NET/ASP.NET Routing路由(深入解析路由系统架构原理) 阅读目录: 1.开篇介绍 2.ASP.NET Routing 路由对象模型的位置 3.ASP.NET Routing 路由对象模型的入口 4.ASP.NET Routing 路由对象模型的内部结构 4.1UrlRoutingModule 对象内部结构 4.2RouteBase.Route.RouteCollection.RouteTable 路由核心对象模型 4.3RouteValueDictionary.RouteData

.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.1]UrlRoutingModule 对象内部结构 4.2]RouteBase.Route.RouteCollection.RouteTable 路由核心对象模型 4.3]RouteValueDictionary.RouteData.RequestContext 路由数据对象模型 4.4]IRou

给Asp.Net MVC及WebApi添加路由优先级

一.为什么需要路由优先级 大家都知道我们在Asp.Net MVC项目或WebApi项目中注册路由是没有优先级的,当项目比较大.或有多个区域.或多个Web项目.或采用插件式框架开发时,我们的路由注册很可能不是写在一个文件中的,而是分散在很多不同项目的文件中,这样一来,路由的优先级的问题就突显出来了. 比如: App_Start/RouteConfig.cs中 routes.MapRoute( name: "Default", url: "{controller}/{action

【Web API系列教程】2.1 — ASP.NET Web API中的路由机制

这篇文章描述了ASP.NET Web API如何将HTTP请求发送(路由)到控制器. 备注:如果你对ASP.NET MVC很熟悉,你会发现Web API路由和MVC路由非常相似.主要区别是Web API使用HTTP方法来选择动作(action),而不是URI路径.你也可以在Web API中使用MVC风格的路由.这篇文章不需要ASP.NET MVC的任何知识. 路由表 在ASP.NET Web API中,控制器是一个用于处理HTTP请求的类.控制器中的公共方法被称为动作方法或简单动作.当Web A

ASP.NET MVC 3中的路由

准备发布新随笔,才发现草稿里还有几年前这篇烂了尾的,先放上来,有空再补完整吧-- (* 整理自<Pro ASP.NET MVC 3 Framework>学习笔记. *) 路由,正如其名,是决定消息经由何处被传递到何处的过程.也正如网络设备路由器Router一样,ASP.NET MVC框架处理请求URL的方式,同样依赖于一张预定义的路由表.以该路由表为转发依据,请求URL最终被传递给特定Controller的特定Action进行处理.而在相反的方向上,MVC框架的渲染器同样要利用这张路由表,生成

asp.net web api使用默认路由 put delete动作在IIS下受限

asp.net web api使用默认路由 1. put.delete动作在IIS中受限(可通过remove WebDAV,方法见上一篇) 2.每个controller可写action有限,在单个业务操作较多的情况下需要建立多个controller 使用新路由,仅使用Get.Post动作 protected void Application_Start(object sender, EventArgs e) { var config = GlobalConfiguration.Configura

IIS7下部署asp.net mvc及asp.net web pages的问题

在IIS7下部署asp.net mvc和asp.net web pages一不小心就会遇到文件找不到的错误,如下图所示: 发生这种问题的根本原因在于IIS7考虑了很多兼容性的东西,解决该问题的方法也很简单就是在配置文件中加入如下的配置项:   <system.webServer> <modules runAllManagedModulesForAllRequests="true"/> </system.webServer>   同类型的问题有不少呢:

[译] ASP.NET 生命周期 – ASP.NET 上下文对象(五)

ASP.NET 上下文对象 ASP.NET 提供了一系列对象用来给当前请求,将要返回到客户端的响应,以及 Web 应用本身提供上下文信息.间接的,这些上下文对象也可以用来回去核心 ASP.NET 框架特性. 上下文对象提供了应用,当前请求,与当前请求相关联的响应的信息.也提供了对多数重要的 ASP.NET 平台服务的访问,比如安全与状态数据.我们可以在 MVC 框架的 controllers 和 views 中使用上下文对象来根据当前的请求或者应用状态数据来调整我们应用的响应.在创建模块或者处理