路由负责匹配传入的 HTTP 请求,然后将这些请求发送到应用的可执行终结点。 终结点是应用的可执行请求处理代码单元。 终结点在应用中进行定义,并在应用启动时进行配置。 终结点匹配过程可以从请求的 URL 中提取值,并为请求处理提供这些值。 通过使用应用中的终结点信息,路由还能生成映射到终结点的 URL。
应用可以使用以下内容配置路由:
Controller
Razor Pages
SignalR
gRPC
- 启用终结点的中间件,例如运行状况检查。
- 通过路由注册的委托和 Lambda。
路由基本知识
以下代码演示路由的基本示例:
1 | var builder = WebApplication.CreateBuilder(args); |
前面的示例包含使用 MapGet 方法的单个终结点:
- 当 HTTP GET 请求发送到根 URL / 时:
- 将执行请求委托。
- Hello World! 会写入 HTTP 响应。
- 如果请求方法不是 GET 或根 URL 不是 /,则无路由匹配,并返回 HTTP 404。
路由使用一对由 UseRouting
和 UseEndpoints
注册的中间件:
UseRouting
:向中间件管道添加路由匹配。 此中间件会查看应用中定义的终结点集,并根据请求选择最佳匹配。UseEndpoints
: 向中间件管道添加终结点执行。 它会运行与所选终结点关联的委托。
应用通常不需要调用 UseRouting
或 UseEndpoints
。 WebApplicationBuilder
配置中间件管道,该管道使用 UseRouting
和 UseEndpoints
包装在 Program.cs 中添加的中间件。 但是,应用可以通过显式调用这些方法来更改 UseRouting
和 UseEndpoints
的运行顺序。 例如,下面的代码显式调用 UseRouting
:
1 | app.Use(async (context, next) => |
在上述代码中:
- 对
app.Use
的调用会注册一个在管道的开头运行的自定义中间件。 - 对
UseRouting
的调用将路由匹配中间件配置为在自定义中间件之后运行。 - 使用
MapGet
注册的终结点在管道末尾运行。
如果前面的示例不包含对 UseRouting 的调用,则自定义中间件将在路由匹配中间件之后运行。
终结点
MapGet
方法用于定义终结点。终结点可以:
- 通过匹配URL和HTTP方法来选择
- 通过运行委托来运行
可通过应用匹配和执行的终结点在 UseEndpoints
中进行配置。 例如,MapGet
、MapPost
和MapGet
将请求委托连接到路由系统。 其他方法可用于将 ASP.NET Core 框架功能连接到路由系统:
- 用于 Razor Pages 的
MapRazorPages
- 用于 控制器 的
MapControllers
- 用于 SignalR 的
MapHub<THub>
- 用于 gRPC 的
MapGrpcService<TService>
路由概念
路由系统通过添加功能强大的终结点概念,构建在中间件管道之上。 终结点代表应用的功能单元,在路由、授权和任意数量的 ASP.NET Core 系统方面彼此不同。
终结点定义
ASP.NET Core 终结点是:
- 可执行:具有
RequestDelegate
。 - 可扩展:具有元数据(
Endpoint.Metadata
)集合 - Selectable:可选择性包含路由信息(
RouteEndpoint.RoutePattern
)。 - 可枚举:可通过从
EndpointDataSource
中检索EndpointDataSource
来列出终结点集合。
以下代码显示了如何检索和检查与当前请求匹配的终结点:
1 | app.Use(async (context, next) => |
如果选择了终结点,可从 HttpContext
中进行检索。 可以检查其属性。 终结点对象是不可变的,并且在创建后无法修改。 最常见的终结点类型是 RouteEndpoint
。 RouteEndpoint
包括允许自己被路由系统选择的信息。
- 调用
UseRouting
之前,终结点始终为null
。 - 如果找到匹配项,则
UseRouting
和UseEndpoints
之间的终结点为非null
。 - 如果找到匹配项,则
UseEndpoints
中间件即为终端。 - 仅当找不到匹配项时才执行
UseEndpoints
后的中间件。
在UseRouting
之前使用app.Use
中调用context.GetEndpoint()
为null
;在UseRouting
之后才不为空
UseRouting
中间件使用 SetEndpoint
方法将终结点附加到当前上下文。 可以将 UseRouting
中间件替换为自定义逻辑,同时仍可获得使用终结点的益处。 终结点是中间件等低级别基元,不与路由实现耦合。 大多数应用都不需要将 UseRouting
替换为自定义逻辑。
UseEndpoints
中间件旨在与 UseRouting
中间件配合使用。 执行终结点的核心逻辑并不复杂。 使用 GetEndpoint
检索终结点,然后调用其 RequestDelegate
属性。
下面的代码演示中间件如何影响或响应路由:
1 | public class RequiresAuditAttribute : Attribute { } |
1 | app.UseHttpMethodOverride(); |