65.9K
CodeProject 正在变化。 阅读更多。
Home

ASP.NET MVC 路由完全入门指南

starIconstarIconstarIconstarIconstarIcon

5.00/5 (12投票s)

2014年6月13日

CPOL

5分钟阅读

viewsIcon

47459

在本文中,我们将尝试理解 ASP.NET MVC 路由。我们将了解有关路由的详细信息,并尝试了解如何实现路由约束。

引言

在本文中,我们将尝试理解 ASP.NET MVC 路由。我们将了解有关路由的详细信息,并尝试了解如何实现路由约束。

背景

来自 ASP.NET Webforms 背景的开发人员在开始使用 MVC 时,发现很难理解请求如何映射到控制器的操作,以及最终如何在屏幕上呈现视图。在 Web forms 中,请求实际上是映射到应用程序目录中物理存在的页面。但在 ASP.NET MVC 中,每个请求都需要映射到一个控制器。ASP.NET MVC 中不存在物理 ASPX 文件的概念。

在 ASP.NET MVC 中,我们有控制器。每个控制器将有多个操作,每个操作都应该处理用户请求。用户请求的 URL 如何映射到控制器的操作方法?这个问题的答案就是 ASP.NET MVC 中的路由机制。路由是用户请求的 URL 与控制器操作方法之间的桥梁。路由负责映射请求 URL 到控制器和操作方法的映射策略。

这并不意味着我们必须手动映射所有 URL 到控制器和操作。ASP.NET MVC 通过指定一些路由(可以看作是提示/模式)来提供自动路由的机制。这些提示/模式将使路由模块能够理解请求的 URL 以及要调用的相应控制器和操作。

为了让路由引擎更好地理解,我们可以在路由中指定以下内容:

  • 模式:这有助于解析器理解如何分解请求的 URL 并将其映射到特定的控制器和操作。
  • 路由参数:这允许引擎理解路由中传入的参数,并将它们映射到操作方法的参数。
  • 路由约束:这允许解析器知道正在传递的参数的类型(字符串/整数)。
  • 忽略规则:这允许解析器知道哪些路由或路由模式应该被忽略。

使用代码

为了更好地理解上述概念,让我们创建一个简单的空 MVC 4 Web 应用程序。我们将看到如何为该应用程序指定各种路由。

所有路由信息都存储在一个名为 RouteCollection 的集合中。如果我们想为应用程序指定路由模式,我们需要在应用程序启动时将这些模式添加到此集合中。MVC 4 项目模板提供了一个已添加到 RouteCollection 的默认路由。此默认路由存在于 RouteConfig.cs 文件的 RegisterRoutes 方法中。此方法从 global.asax 文件中的 Application_Start 生命周期事件中调用。让我们看看这个默认路由并尝试理解它的模式。

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

第一个属性是路由的名称。我们添加到路由集合的每个路由都应该有一个唯一的名称,以便能够唯一地识别它。第二个属性是 URL,它指定了请求 URL 的模式,如 {controller}/{action}/{id}。因此,如果用户请求一个 URL,例如:www.example.com/Customer/Edit/1,此 URL 将调用 Customer 控制器的 Edit Action 方法,并将 id 参数设置为 1。第三个属性指定了 controller、action 和 id 参数的默认值,即,如果用户请求 www.example.com,由于 URL 中缺少 controller、action 和 id 部分,路由引擎将采用默认值并调用 Home 控制器的 Index action,且不带 id 参数(因为它是可选的)。

现在,首先想到的问题是——如果我们必须向操作方法提供 2 个参数怎么办?嗯,这很简单。我们只需要在路由中指定多个参数值。

routes.MapRoute(
    name: "multipleparams",
    url: "{controller}/{action}/{param1}/{param2}",
    defaults: new { controller = "Home", action = "Action2", param1 = UrlParameter.Optional, param2 = UrlParameter.Optional }
);

同样,我们可以在路由模式中指定任意数量的路由参数。此外,我们可以选择将这些参数中的任何一个设为可选。

路由约束

路由约束主要用于限制匹配特定路由的请求 URL。这可以用于限制对我们的应用程序无效的路由。路由约束以正则表达式的形式指定。让我们通过定义一个简单的操作方法来编辑实体来尝试理解这个问题。我们来为它定义操作方法。

public class HomeController : Controller
{
    public ActionResult Edit(int id)
    {
        ViewBag.Message = "Home/Edit/" + id;
        return View();
    }
}

现在,此操作方法期望传递一个 int 值给它。有一个用于此操作方法的视图,它只是显示路由。所以让我们用以下 URL 调用此操作方法:“Home/Edit/1”。结果将是

发生的情况是,我们的默认路由足以让路由引擎解析请求的 URL 并调用 Edit action。现在,让我们尝试在路由中传递一个无效的 int 值,即“Home/Edit/test”。结果现在是

原因是,非整数值对此操作方法无效。因此,对于我们的应用程序来说,这是一个无效的路径,为了将此路径标记为无效路径,我们可以定义一个带有路由约束的自定义路由。让我们尝试用路由约束来定义这个路由。

routes.MapRoute(
    name: "home_Edit",
    url: "Home/Edit/{id}",
    defaults: new { controller = "Home", action = "Edit" },
    constraints: new { id = @"\d+" }
);

此路由现在只会接受此路由的有效数字值。现在,如果我们再次尝试访问相同的 URL,浏览器将清楚地表明这是一个无效的 URL。

忽略某些路由

在某些情况下,我们也希望完全忽略某些路由。如果我们查看 RouteConfig 类,我们可以看到类似的代码

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

这会限制对所有以 .axd 扩展名结尾的 URL 的访问,因为我们不希望最终用户能够访问 Trace.axd 或其他资源 axd 文件。

在结束这个小提示之前,有一件重要的事情要记住。将路由插入 RouteCollection 的顺序非常重要。路由模块,即路由处理程序,将从上到下开始查看此映射。因此,如果我们想在通用路由的同时放入一些特定的路由,我们应该将特定的路由放在通用路由之前。

关注点

在这篇小文章中,我们讨论了 ASP.NET 路由的基础知识。这是从绝对初学者的角度编写的。我希望这能提供信息。

历史

  • 2014 年 6 月 13 日:初始版本
© . All rights reserved.