3.5 路由 (Routing)


文档摘要

3.5 路由 (Routing) 3.5 路由 (Routing) in ASP.NET Core MVC 路由是 ASP.NET Core MVC 应用的核心机制,它负责将传入的 HTTP 请求映射到应用程序中的特定控制器操作 (Action)。理解和掌握路由机制对于构建高效、可维护的 Web 应用至关重要。 3.5.1 路由的基本概念 路由本质上是一个模式匹配过程。当一个 HTTP 请求到达 ASP.NET Core 应用时,路由中间件会根据预定义的路由规则,尝试将请求的 URL 与这些规则进行匹配。如果找到匹配的规则,则会将请求转发到相应的控制器和操作。 关键概念包括: 路由规则 (Route Rule): 定义了 URL 模式和对应的控制器/操作之间的映射关系。

3.5 路由 (Routing)

3.5 路由 (Routing) in ASP.NET Core MVC

路由是 ASP.NET Core MVC 应用的核心机制,它负责将传入的 HTTP 请求映射到应用程序中的特定控制器操作 (Action)。理解和掌握路由机制对于构建高效、可维护的 Web 应用至关重要。

3.5.1 路由的基本概念

路由本质上是一个模式匹配过程。当一个 HTTP 请求到达 ASP.NET Core 应用时,路由中间件会根据预定义的路由规则,尝试将请求的 URL 与这些规则进行匹配。如果找到匹配的规则,则会将请求转发到相应的控制器和操作。

关键概念包括:

  • 路由规则 (Route Rule): 定义了 URL 模式和对应的控制器/操作之间的映射关系。

  • 路由模板 (Route Template): 定义了 URL 的结构,可以包含字面值和参数。

  • 路由参数 (Route Parameter): URL 中可以动态变化的部分,用于传递数据给控制器操作。

  • 路由约束 (Route Constraint): 限制路由参数的取值范围,例如只能是整数或特定格式的字符串。

  • 路由处理程序 (Route Handler): 实际处理匹配到的路由的组件,通常是 MVC 控制器。

3.5.2 路由的配置方式

ASP.NET Core MVC 提供了多种配置路由的方式,最常见的是使用终结点路由(Endpoint Routing)。

3.5.2.1 终结点路由 (Endpoint Routing)

终结点路由是 ASP.NET Core 3.0 引入的路由机制,它提供了更强大的功能和更好的性能。 在 Startup.cs 文件的 Configure 方法中,使用 UseEndpoints 方法来配置终结点路由。

public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); // 启用路由中间件 app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); // 可以添加更多的路由规则 }); }

代码解释:

  • app.UseRouting(): 将路由中间件添加到请求管道中。

  • app.UseEndpoints(): 配置终结点路由。

  • endpoints.MapControllerRoute(): 映射一个标准的 MVC 控制器路由。

    • name: 路由名称,用于在代码中引用该路由。

    • pattern: 路由模板,定义了 URL 的结构。

      • {controller=Home}: 控制器参数,默认值为 "Home"。

      • {action=Index}: 操作参数,默认值为 "Index"。

      • {id?}: 可选的 ID 参数。 ? 表示该参数是可选的。

示例:

  • / -> HomeController.Index()

  • /Home -> HomeController.Index()

  • /Home/Index -> HomeController.Index()

  • /Home/About -> HomeController.About()

  • /Products/Details/123 -> ProductsController.Details(id = 123)

3.5.2.2 特性路由 (Attribute Routing)

特性路由允许直接在控制器和操作上定义路由规则,使路由配置更加直观和集中。 使用 [Route] 特性来指定路由模板。

using Microsoft.AspNetCore.Mvc; namespace MyWebApp.Controllers { [Route("products")] // 控制器级别的路由 public class ProductsController : Controller { [Route("")] // 匹配 /products [Route("index")] // 匹配 /products/index public IActionResult Index() { return View(); } [Route("details/{id:int}")] // 匹配 /products/details/{id},id 必须是整数 public IActionResult Details(int id) { ViewBag.Id = id; return View(); } [Route("create")] //匹配 /products/create public IActionResult Create() { return View(); } } }

代码解释:

  • [Route("products")]: 定义了控制器级别的路由前缀。所有该控制器下的操作都将以 /products 开头。

  • [Route("")]: 表示匹配控制器路由前缀本身,即 /products

  • [Route("index")]: 表示匹配 /products/index

  • [Route("details/{id:int}")]: 定义了一个带参数的路由,{id:int} 表示 id 参数必须是整数类型。这就是一个路由约束。

3.5.2.3 混合路由 (Combined Routing)

可以同时使用终结点路由和特性路由,但这需要谨慎。 终结点路由通常用于定义默认路由和回退路由,而特性路由用于定义更具体的路由规则。

如果同时使用,特性路由会覆盖终结点路由。因此,建议尽量使用一种路由方式,以避免混淆。

3.5.3 路由参数和约束

路由参数是从 URL 中提取数据并传递给控制器操作的关键机制。路由约束用于限制路由参数的取值范围,以确保数据的有效性。

3.5.3.1 路由参数

路由参数使用花括号 {} 括起来,可以定义参数名称和可选的默认值。

[Route("articles/{year}/{month}/{day}")] public IActionResult Articles(int year, int month, int day) { // ... }

在这个例子中,yearmonthday 是路由参数。 当 URL 匹配到该路由时,这些参数的值将被提取并传递给 Articles 操作。

3.5.3.2 路由约束

路由约束使用冒号 : 后跟约束名称来定义。ASP.NET Core 提供了许多内置的路由约束,例如:

  • int: 限制参数为整数。

  • bool: 限制参数为布尔值。

  • datetime: 限制参数为日期时间。

  • minlength(n): 限制参数的最小长度为 n

  • maxlength(n): 限制参数的最大长度为 n

  • range(min,max): 限制参数的取值范围在minmax之间。

  • regex(pattern): 使用正则表达式匹配参数。

[Route("products/{id:int:min(1)}")] // id 必须是大于等于 1 的整数 public IActionResult Details(int id) { // ... } [Route("users/{username:regex(^[a-zA-Z]+$)}")] // username 只能包含字母 public IActionResult Profile(string username) { // ... }

3.5.3.3 自定义路由约束

可以创建自定义的路由约束,以满足特定的需求。 需要实现 IRouteConstraint 接口。

using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing; using System.Text.RegularExpressions; public class MobileRouteConstraint : IRouteConstraint { public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection) { if (!values.ContainsKey(routeKey)) { return false; } var mobile = values[routeKey]?.ToString(); if (string.IsNullOrEmpty(mobile)) { return false; } // 简单的手机号验证 return Regex.IsMatch(mobile, @"^1[3456789]\d{9}$"); } }

然后,需要在 Startup.cs 中注册自定义路由约束:

public void ConfigureServices(IServiceCollection services) { services.Configure<RouteOptions>(options => { options.ConstraintMap.Add("mobile", typeof(MobileRouteConstraint)); }); services.AddControllersWithViews(); }

最后,可以在路由中使用自定义约束:

[Route("sms/{mobile:mobile}")] public IActionResult SendSms(string mobile) { // ... }

3.5.4 路由的优先级

当多个路由规则匹配同一个 URL 时,路由引擎会根据优先级来选择最佳匹配。 路由优先级的规则如下:

  1. 更具体的路由优先: 包含更多字面值的路由优先。

  2. 包含约束的路由优先: 包含约束的路由优先。

  3. 显式定义的路由优先: 使用 MapControllerRoute 或特性路由定义的路由优先于默认路由。

  4. 注册顺序: 如果以上规则无法区分,则按照路由注册的顺序选择,先注册的路由优先。

3.5.5 生成 URL

除了将 URL 映射到控制器操作之外,路由还可以用于生成 URL。 可以使用 IUrlHelper 接口来生成 URL。

public class HomeController : Controller { private readonly IUrlHelper _urlHelper; public HomeController(IUrlHelper urlHelper) { _urlHelper = urlHelper; } public IActionResult Index() { var url = _urlHelper.Action("Details", "Products", new { id = 123 }); // 生成 /products/details/123 ViewBag.ProductDetailsUrl = url; return View(); } }

代码解释:

  • _urlHelper.Action(): 根据指定的控制器、操作和路由参数生成 URL。

也可以使用 asp-route-{parameter} 标签助手在 Razor 视图中生成 URL:

<a asp-controller="Products" asp-action="Details" asp-route-id="456">Product Details</a>

这将生成一个指向 /products/details/456 的链接。

3.5.6 路由的调试和诊断

ASP.NET Core 提供了一些工具来帮助调试和诊断路由问题:

  • 路由调试中间件: 可以显示每个请求匹配到的路由规则。 需要安装 Microsoft.AspNetCore.Diagnostics 包,并在 Startup.cs 中配置中间件。

  • 日志记录: 路由引擎会记录路由匹配的信息,可以查看日志来了解路由匹配的过程。

3.5.7 路由流程图

graph TD A[HTTP 请求] --> B(路由中间件); B --> C{匹配路由规则?}; C -- 是 --> D[执行控制器操作]; C -- 否 --> E[返回 404 Not Found]; D --> F[生成 HTTP 响应]; F --> G[客户端]; E --> G;

3.5.8 总结

路由是 ASP.NET Core MVC 应用的关键组成部分,它负责将 URL 映射到控制器操作,并生成 URL。 通过理解和掌握路由的配置方式、路由参数和约束、路由优先级以及 URL 生成,可以构建灵活、可维护的 Web 应用。 特性路由和终结点路由是两种主要的路由配置方式,可以根据实际需求选择使用。 路由约束可以用于限制路由参数的取值范围,确保数据的有效性。 IUrlHelper 和标签助手可以用于生成 URL。 路由调试中间件和日志记录可以帮助调试和诊断路由问题。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U