概述
在 ASP.NET 网站中,URL 通常映射到存储在磁盘上的文件(通常为 .aspx 文件)。 这些 .aspx 文件包括经过处理以响应请求的标记和代码。
ASP.NET MVC 框架将 URL 映射到不同于 ASP.NET Web 窗体页面的服务器代码。 该框架会将 URL 映射到 controller 类,而不是将 URL 映射到 ASP.NET 页面或处理程序。 Controller 类将处理传入的请求,如用户输入和交互,并根据用户输入执行相应的应用程序和数据逻辑。 Controller 类通常会调用一个生成 HTML 输出作为响应的单独视图组件。
ASP.NET MVC 框架会将模型、视图和控制器组件分开。 模型表示应用程序的业务/域逻辑,通常具有数据库支持的数据。 视图由控制器进行选择,并呈现相应的 UI。 默认情况下,ASP.NET MVC 框架使用现有的 ASP.NET 页面 (.aspx)、母版页 (.master) 和用户控件 (.ascx) 类型呈现到浏览器。 控制器将在自身中查找相应的操作方法,获取要用作操作方法参数的值,并处理可能会在运行操作方法时发生的任何错误。 然后,它将呈现请求的视图。 默认情况下,每组组件都位于 MVC Web 应用程序项目的单独文件夹中。
回顾
MVC应用程序的执行过程
发送给基于 ASP.NET MVC 的 Web 应用程序的请求首先通过 UrlRoutingModule 对象(一个 HTTP 模块)进行传递。 此模块将分析请求并执行路由选择。 UrlRoutingModule 对象将选择与当前请求匹配的第一个路由对象。 (路由对象是实现 RouteBase 的类,并且通常是 Route 类的实例。) 如果任何路由都不匹配,则 UrlRoutingModule 对象不执行任何操作,并允许请求回退到常规的 ASP.NET 或 IIS 请求处理流程。
从选定的 Route 对象中,UrlRoutingModule 对象将获得一个对象,所获得的对象将实现 IRouteHandler 接口并与 Route 对象关联。 通常,在 MVC 应用程序中,这将是 MvcRouteHandler 类的一个实例。 MvcRouteHandler 实例将创建一个实现 IHttpHandler 接口的 MvcHandler 对象。 然后,MvcHandler 对象会选择将最终处理该请求的控制器。
UrlRoutingModule 和 MvcRouteHandler 类是 ASP.NET MVC 框架的入口点。 它们执行下列操作:
-
选择 MVC Web 应用程序中合适的控制器。
-
获取特定的控制器实例。
-
调用该控制器的 Execute 方法。
下表列出了 MVC Web 项目的执行阶段。
阶段 | 详细信息 |
---|---|
接收对应用程序的第一个请求 | 在 Global.asax 文件中,Route 对象将添加到 RouteTable 对象中。 |
执行路由 | UrlRoutingModule 模块使用 RouteTable 集合中第一个匹配的 Route 对象来创建 RouteData 对象,然后使用所创建的对象创建 RequestContext 对象。 |
创建 MVC 请求处理程序 | MvcRouteHandler 对象将创建 MvcHandler 类的实例,并将 RequestContext 实例传递给处理程序。 |
创建控制器 | MvcHandler 对象使用 RequestContext 实例标识用于创建控制器实例的 IControllerFactory 对象(通常是 DefaultControllerFactory 类的实例)。 |
执行控制器 | MvcHandler 实例调用控制器的 Execute 方法。 |
调用操作 | 对于从 ControllerBase 类继承的控制器,与该控制器关联的 ControllerActionInvoker 对象将决定要调用的 controller 类的操作方法,然后调用该方法。 |
执行结果 | 操作方法将接收用户输入,准备合适的响应数据,然后通过返回结果类型来执行结果。 可执行的内置结果类型包括:ViewResult(呈现视图并且是最常用的结果类型)、RedirectToRouteResult、RedirectResult、ContentResult、JsonResult、FileResult 和 EmptyResult。 |
基础概念
UrlRoutingModule 类
匹配定义的路由的 URL 请求。
UrlRoutingModule 类匹配 ASP.NET 应用程序中的路由的 HTTP 请求。 该模块循环访问 RouteCollection 属性中的所有路由,并搜索具有与 HTTP 请求的格式匹配的 URL 模式的路由。 该模块找到匹配路由后,它会检索 IRouteHandler 对象,以查找该路由。 该模块会从该路由处理程序获取一个 IHttpHandler 对象,并将该对象用作当前请求的 HTTP 处理程序。
UrlRoutingModule.RouteCollection 属性
获取或设置 ASP.NET 应用程序的定义路由的集合。包含路由的对象的集合。
IRouteHandler 接口
定义类必须实现才能处理匹配路由模式的请求的协定。
IRouteHandler.GetHttpHandler 方法
提供处理请求的对象。参数为一个System.Web.Routing.RequestContext对象,封装有关请求的信息。返回一个处理请求的System.Web.IHttpHandler对象。
IHttpHandler 接口
定义 ASP.NET 为使用自定义 HTTP 处理程序同步处理 HTTP Web 请求而实现的协定。
ControllerBase.Execute 方法
执行指定的请求上下文。
RouteTable 类
存储应用程序的 URL 路由。
路由是用于处理请求的 URL 模式,可用于动态构造 URL。 Routes 属性是一个 static 属性(在 Visual Basic 中为 Shared),它包含应用程序中用于指定 URL 请求于处理该请求的类匹配的方式的所有路由。 若要指定路由,您可以将路由定义添加到 Routes 属性中。 通常情况下,您可以将路由添加到 Global.asax 文件中的 Application_Start 事件的事件处理程序的 Routes 属性中。
当 ASP.NET 应用程序处理请求时,该应用程序会循环访问 Routes 属性中的路由集合,以便查找与 URL 请求的格式匹配的路由。 您添加到 Routes 属性的路由的顺序非常重要,因为应用程序会使用它在与 URL 匹配的集合中找到的第一个路由。
RouteTable.Routes 属性
获取从 RouteBase 类派生的对象的集合。
MVC 包括以下处理程序类型:
-
MvcHandler. 此处理程序负责启动用于 MVC 应用程序的 ASP.NET 管道。 它从 MVC 控制器工厂接收 Controller 实例;此控制器处理请求的进一步处理。 注意,即使 MvcHandler 实现 IHttpHandler,也不能将其映射为处理程序(例如,.mvc 文件扩展名),因为该类不支持无参数构造函数。 (它唯一的构造函数需要一个 RequestContext 对象。)
-
MvcRouteHandler. 此类实现了 IRouteHandler,因此可以与 ASP.NET 路由集成。 MvcRouteHandler 类将路由与 MvcHandler 实例关联。 当您使用 MapRoute 方法时,向路由注册 MvcRouteHandler 实例。 当 MvcRouteHandler 类被调用时,该类使用当前的 RequestContext 实例产生 MvcHandler 实例。 然后它会将控制委托给新 MvcHandler 实例。
-
MvcHttpHandler. 此处理程序用于在不通过路由模块的情况下帮助直接处理程序映射。 如果您希望一个文件的扩展名(如 .mvc)直接映射到一个 MVC 处理程序,这很有用。 在内部,MvcHttpHandler 执行 ASP.NET 路由通常执行的相同任务(通过 MvcRouteHandler 和 MvcHandler)。 但是,它将这些任务作为处理程序而不是模块来执行。 UrlRoutingModule 为所有请求启用时,通常不使用此处理程序。
Url路由
ASP.NET MVC 框架将使用 ASP.NET 路由引擎,通过该引擎可以灵活地将 URL 映射到 controller 类。 您可以定义 ASP.NET MVC 框架使用的路由规则,以评估传入的 URL 以及选择相应的控制器。 您还可以让该路由引擎自动分析 URL 中定义的变量,并让 ASP.NET MVC 框架将值作为参数自变量传递给控制器。
路由
“路由”是映射到处理程序的 URL 模式。 处理程序可以是物理文件,例如 Web 窗体应用程序中的 .aspx 文件。 处理程序还可以是处理请求的类,例如 MVC 应用程序中的控制器。 若要定义路由,可以通过指定 URL 模式、处理程序和(可选)路由名称,创建 Route 类的一个实例。
通过将 Route 对象添加到 RouteTable 类的静态 Routes 属性,向应用程序中添加路由。 Routes 属性是一个存储应用程序的所有路由的 RouteCollection 对象。
通常不必编写代码来在 MVC 应用程序中添加路由。 MVC 的 Visual Studio 项目模板包含预先配置的 URL 路由。 它们是在 MvcApplication 类中定义的,该类是在 Global.asax 文件中定义的。
特性
ASP.NET 路由使您可以使用不必映射到网站中特定文件的 URL。 由于该 URL 不必映射到文件,因此可以使用对用户操作进行描述因而更易于被用户理解的 URL。
在不使用路由的 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 模式
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}
Global.asax默认路由
public static void RegisterRoutes(RouteCollection routes) { //忽略对.axd文件的Route,也就是和WebForm一样直接去访问.axd文件 routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( "Default", // 路由名称 "{controller}/{action}/{id}", // 带有参数的 URL new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 参数默认值 ); } protected void Application_Start() { //在程序启动的时候注册我们前面定义的Route规则 RegisterRoutes(RouteTable.Routes); }
总结
我们从MVC程序的运行开始一步一步,深入了解了MVC程序使用其强大的Routing规则,使我们使用和开发MVC程序都有了新的体验和认识。从而在一定基础上保护了程序的健壮性。*