简介
定义:通过使用应用中的终结点信息,路由还能生成映射到终结点的 URL。
在ASP.NET Core中是使用路由中间件来匹配传入请求的 URL 并将它们映射到操作(action方法)。路由是在程序启动时进行传统路由或属性路由定义。 路由描述如何将 URL 路径与操作相匹配。 它还用于在响应中生成送出的 URL(用于链接)。
路由操作既支持传统路由,也支持属性路由。也可混合使用。通常传统路由用于为浏览器处理 HTML 页面的控制器。属性路由用于处理 web API 的控制器。
官方文档:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/routing?view=aspnetcore-3.1
web路由:https://docs.microsoft.com/zh-cn/aspnet/core/mvc/controllers/routing?view=aspnetcore-3.1
路由中间件
//向中间件管道添加路由匹配。 此中间件会查看应用中定义的终结点集,并根据请求选择最佳匹配。 app.UseRouting(); //向中间件管道添加终结点执行。 它会运行与所选终结点关联的委托。(通过map..等方法定义终结点) app.UseEndpoints(endpoints => { //映射默认路由 {controller=Home}/{action=Index}/{id?} //endpoints.MapDefaultControllerRoute(); //endpoints.MapControllerRoute( // name: "default", // pattern: "{controller=Home}/{action=Index}/{id?}"); //endpoints.MapControllerRoute("api", "api/{controller}/{action}"); //使用RouteAttribute endpoints.MapControllers(); //添加终结点 可以理解mapget是一个终结点 (通过匹配 URL 和 HTTP 方法来选择。 通过运行委托来执行。 进而讲请求连接到路由系统) endpoints.MapGet( "/hello/{name:alpha}",//路由模板 用于配置终结点的匹配方式 : 是路由约束。 URL 路径的第二段 {name:alpha}绑定到 name 参数,捕获并存储在 HttpRequest. RouteValues 中 async context => { var name = context.Request.RouteValues["name"]; await context.Response.WriteAsync($"Hello {name}!"); }); //当 HTTP GET 请求发送到根 URL / 时: //将执行显示的请求委托。 //Hello World!会写入 HTTP 响应。 默认情况下,根 URL / 为 https://localhost:5001/。 //如果请求方法不是 GET 或根 URL 不是 /,则无路由匹配,并返回 HTTP 404。 endpoints.MapGet("/", async context => { await context.Response.WriteAsync("Hello World!"); }); });
UseRouting 向中间件管道添加路由匹配。 此中间件会查看应用中定义的终结点集,并根据请求选择最佳匹配。
UseEndpoints 向中间件管道添加终结点执行。 它会运行与所选终结点关联的委托。
UseRouting 和 UseEndpoints 之间,因此它们可以:
- 查看
UseRouting选择的终结点。 - UseEndpoints 发送到终结点之前应用授权策略。
终结点
我们说路由的根本目的是将用户请求地址,映射为一个请求处理器,最简单的请求处理器可以是一个委托 Func<HttpCotnext,Task>,也可以是mvc/webapi中某个controller的某个action,所以从抽象的角度讲 一个终结点 就是一个处理请求的委托。由于mvc中action上还有很多attribute,因此我们的终结点还应该提供一个集合,用来存储与此请求处理委托的关联数据。
一个终结点 = 处理请求的委托 + 与之关联的附加(元)数据
public void ConfigureServices(IServiceCollection services) { services.AddControllers(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
- 第一步:执行services.AddControllers()
将Controller的核心服务注册到容器中去 - 第二步:执行app.UseRouting()
将EndpointRoutingMiddleware中间件注册到http管道中 - 第三步:执行app.UseAuthorization()
将AuthorizationMiddleware中间件注册到http管道中 - 第四步:执行app.UseEndpoints(encpoints=>endpoints.MapControllers())
有两个主要的作用:
调用endpoints.MapControllers()将本程序集定义的所有Controller和Action转换为一个个的EndPoint放到路由中间件的配置对象RouteOptions中
将EndpointMiddleware中间件注册到http管道中
public static IApplicationBuilder UseRouting(this IApplicationBuilder builder) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } VerifyRoutingServicesAreRegistered(builder); var endpointRouteBuilder = new DefaultEndpointRouteBuilder(builder); builder.Properties[EndpointRouteBuilder] = endpointRouteBuilder; return builder.UseMiddleware<EndpointRoutingMiddleware>(endpointRouteBuilder); }