[转]ASP.NET MVC URL 路由简介
URL 路由简介
在本教程中,将介绍对于每个 ASP.NET MVC 应用程序都非常重要的 URL 路由功能。URL 路由模型负责将进入的浏览器请求映射到特定的 MVC 控制器操作。
在本教程的第一部分中,我们将学习标准路由表如何将请求映射到控制器操作。在本教程的第二部分中,我们将学习如何使用自定义路由修改默认的路由表。
使用默认路由表
在创建新的 ASP.NET MVC 应用程序时,应用程序已配置好使用 URL 路由。URL 路由在两个位置设置。
第一,URL 路由在应用程序的 Web 配置文件(Web.config 文件)中启用。在配置文件中有 4 个部分与路由有关:system.web.httpModules 部分,system.web.httpHandlers 部分,system.webserver.modules 部分和 system.webserver.handlers 部分。注意不要删除这些部分,因为没有这些部分路由就无法工作。
第二,但是更重要的位置,就是在应用程序中创建路由表的 Global.asax 文件。Global.asax 文件是一个特殊文件,它包含 ASP.NET 应用程序生命周期事件的事件处理程序。路由表是在 Application Start 事件中创建的。
程序清单 1 中的文件包含 ASP.NET MVC 应用程序的默认 Global.asax 文件。
程序清单 1 Global.asax.cs
当 ASP.NET 应用程序第一次启动时,调用 Application_Start() 方法。此方法将调用 RegisterRoutes() 方法。RegisterRoutes() 方法创建路由表。
默认路由表包含一个路由(名称为 Default)。Default 路由将 URL 的第一段映射到控制器名称,将第二段映射到控制器操作,将第三段映射到名称为 id 的参数。
假设将下面的 URL 输入到 Web 浏览器的地址栏:
/Home/Index/3
Default 路由将此 URL 映射为下列参数:
controller = Home
action = Index
id = 3
在请求 URL /Home/Index/3 时,执行下面的代码:
HomeController.Index(3)
Default 路由包括三个参数的默认值。如果不提供控制器,则控制器参数默认为值 Home。如果不提供操作,则操作参数默认为值 Index。最后,如果不提供 id,则 id 参数默认为空字符串。
让我们看几个例子,了解 Default 路由将 URL 映射到控制器操作的方式。假设将下面的 URL 输入到 Web 浏览器的地址栏:
/Home
由于 Default 路由参数的默认值,输入此 URL 将导致调用程序清单 2 中的 HomeController 类的 Index() 方法。
程序清单 2 HomeController.cs
在程序清单 2 中,HomeController 类包含名称为 Index() 的方法,此方法接受一个名称为 id 的参数。URL /Home 导致调用具有空字符串的 Index() 方法作为 id 参数的值。
由于 ASP.NET MVC Framework 激活控制器操作的方式,URL /Home 也可匹配程序清单 3 中的 HomeController 类的 Index() 方法。
程序清单 3 HomeController.cs(没有参数的 Index 操作)
程序清单 3 中的 Index() 方法不接受任何参数。URL /Home 将导致调用 Index() 方法。URL /Home/Index/3 也激活此方法(忽略 Id)。
URL /Home 还可匹配程序清单 4 中的 HomeController 类的 Index() 方法。
程序清单 4 HomeController.cs(带有可以为空的参数的 Index 操作)
在程序清单 4 中,Index() 方法有一个 Integer 参数。因为参数可以为空(值可以是 Nothing),所以可以在不引起错误的情况下调用 Index()。
最后,使用 URL /Home 激活程序清单 5 中的 Index() 方法将导致异常,因为 Id 参数不是可以为空的参数。如果试图激活 Index() 方法,则将得到如图 1 所示的错误页。
程序清单 5 HomeController.cs(带有 Id 参数的 Index 操作)
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace MyApp.Controllers { [HandleError] public class HomeController : Controller { public ActionResult Index(int id) { return View(); } } }
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace MyApp.Controllers { [HandleError] public class HomeController : Controller { public ActionResult Index(int? id) { return View(); } } }
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace MyApp.Controllers { [HandleError] public class HomeController : Controller { public ActionResult Index() { return View(); } } }
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace MyApp.Controllers { [HandleError] public class HomeController : Controller { public ActionResult Index(string Id) { return View(); } } }
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing; namespace MyApp { public class GlobalApplication : 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); } } }
图 1:激活需要参数值的控制器操作( 单击查看大图)
另一方面,URL /Home/Index/3 可以与程序清单 5 中的 Index 控制器操作配合工作。请求 /Home/Index/3 导致调用带有值为 3 的 Id 参数的 Index() 方法。
创建自定义路由
对许多简单的 ASP.NET MVC 应用程序来说,使用默认的路由表就可以了。然而,您也可能会有特殊的路由需求。在这种情况下,应该创建自定义路由。
例如,假设正在创建博客应用程序。需要处理如下所示的进入请求:
/Archive/12-25-2009
当用户输入此请求时,想返回日期为 12/25/2009 的博客条目。为了处理这种类型的请求,需要创建自定义路由。
程序清单 6 中的 Global.asax 文件包含一个新的自定义路由,名称为 Blog,它处理形如 /Archive/条目日期的请求。
程序清单 6 Global.asax(使用自定义路由)
向路由表添加路由的顺序非常重要。新的自定义 Blog 路由添加在现有的 Default 路由之前。如果顺序相反,则将总是调用 Default 路由,而不会调用自定义路由。
自定义 Blog 路由匹配任何以 /Archive/ 开头的请求。所以,它匹配所有下列 URL:
/Archive/12-25-2009
/Archive/10-6-2004
/Archive/apple
自定义路由将进入的请求映射到名称为 Archive 的控制器并激活 Entry() 操作。当调用 Entry() 方法时,条目日期将作为名称为 entryDate 的参数进行传递。
可以将 Blog 自定义路由用在程序清单 7 中的控制器上。
程序清单 7 ArchiveController.cs
请注意,程序清单 7 中的 Entry() 方法接受 DateTime 类型的参数。ASP.NET MVC Framework 可以智能地将 URL 中的条目日期自动转换为 DateTime 值。如果无法将 URL 中的条目日期转换为 DateTime,则将给出错误消息。
总结
本教程的目的是向读者简单介绍 URL 路由。首先,我们研究了新的 ASP.NET MVC 应用程序中的默认路由表。了解了默认路由如何将 URL 映射到控制器操作。
接下来,我们了解了如何创建自定义路由。学习了如何向表示博客条目的 Global.asax 文件添加自定义路由。我们讨论了如何将对博客条目的请求映射到名称为 ArchiveController 的控制器和名称为 Entry() 的控制器操作。
using System; using System.Web.Mvc; namespace MyApp.Controllers { public class ArchiveController : Controller { public string Entry(DateTime entryDate) { return "You requested the entry on " + entryDate.ToString(); } } }
using System.Web.Mvc; using System.Web.Routing; namespace MyApp { public class GlobalApplication : System.Web.HttpApplication { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( "blog", "Archive/{entryDate}", new {controller = "Archive", action = "Entry"} ); 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); } } }