URL 路由简介

这是 Visual C# 教程(转到 Visual Basic 教程

在本教程中,Stephen Walther 将介绍浏览器请求如何通过 URL 路由映射到控制器操作。我们还将学习如何创建根据在 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

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

当 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

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

在程序清单 2 中,HomeController 类包含名称为 Index() 的方法,此方法接受一个名称为 id 的参数。URL /Home 导致调用具有空字符串的 Index() 方法作为 id 参数的值。

由于 ASP.NET MVC Framework 激活控制器操作的方式,URL /Home 也可匹配程序清单 3 中的 HomeController 类的 Index() 方法。

程序清单 3 HomeController.cs(没有参数的 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()
          {
               return View();
          }
     }
}

程序清单 3 中的 Index() 方法不接受任何参数。URL /Home 将导致调用 Index() 方法。URL /Home/Index/3 也激活此方法(忽略 Id)。

URL /Home 还可匹配程序清单 4 中的 HomeController 类的 Index() 方法。

程序清单 4 HomeController.cs(带有可以为空的参数的 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();
          }
     }
}

在程序清单 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();
          }
     }
}

图 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(使用自定义路由)

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

向路由表添加路由的顺序非常重要。新的自定义 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

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

请注意,程序清单 7 中的 Entry() 方法接受 DateTime 类型的参数。ASP.NET MVC Framework 可以智能地将 URL 中的条目日期自动转换为 DateTime 值。如果无法将 URL 中的条目日期转换为 DateTime,则将给出错误消息。

总结

本教程的目的是向读者简单介绍 URL 路由。首先,我们研究了新的 ASP.NET MVC 应用程序中的默认路由表。了解了默认路由如何将 URL 映射到控制器操作。

接下来,我们了解了如何创建自定义路由。学习了如何向表示博客条目的 Global.asax 文件添加自定义路由。我们讨论了如何将对博客条目的请求映射到名称为 ArchiveController 的控制器和名称为 Entry() 的控制器操作。





下一篇教程