用户请求接口路由,应用返回处理惩罚功效。应用中如何匹配请求的数据呢?为何能如此准确的找到对应的处理惩罚要领?本日就谈谈这个路由。路由认真匹配传入的HTTP请求,将这些请求发送到可以执行的终结点。终结点在应用中举办界说而且在应用启动的时候举办设置,也就是在中间件中举办处理惩罚。
路由基本常识在项目新建的时候城市自动生成路由相关代码。在Startup.Configure中的中间件管道注册的。主要涉及到的则是UseRouting和UseEndpoints中间件。
UseRouting向中间件添加路由匹配。此中间件还会查察应用中界说的终结点集。也就是把应用中的路由统统注册到中间件管道,利便请求的时候举办匹配。
UseEndpoints向中间件添加终结点执行。会运行相关联的委托。简朴迁就是路由匹配之后的处理惩罚事件运行。
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapGet("https://www.jb51.net/", async context => { await context.Response.WriteAsync("Hello World!"); }); }); }
譬喻上面的代码就是HTPP GET 请求而且Url是/的时候需要执行的委托、假如这里的请求不是Get请求可能不是"https://www.jb51.net/",那么没有路由匹配,则会返回404。同时指定匹配模式的尚有MapDelete、MapMethods、MapPost、MapPut、Map等。
终结点上面讲的MapGet可能未用到MapPost等就是用于界说终结点的。它们都包括有两个参数,一个是用于Url匹配的,别的一个就是需要执行的委托。这里在纷歧样的应用中都回收了差异的终结点界说要领
用于 Razor Pages 的 MapRazorPages
用于节制器的 MapControllers
用于 SignalR 的 MapHub
用于 gRPC 的 MapGrpcService
那么我们假如需要利用到了授权模块将如那里理惩罚呢,终结点也有相对应的处理惩罚方法。下面就展示将授权中间件和路由一起利用,MapHealthChecks添加运行状况查抄终结点。后头随着的RequireAuthorization则是将授权计策添加到端点。
app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/healthz").RequireAuthorization(); endpoints.MapGet("https://www.jb51.net/", async context => { await context.Response.WriteAsync("Hello World!"); }); });
并且我们看中间的利用顺序,UseAuthentication、UseAuthorization是穿插在UseRouting和UseEndpoints中间的,如此写法例是为了授权计策能在UseRouting中查找终结点,可是能在UseEndpoints发送到终结点执行之前应用所选择的授权计策
终结点元数据上面的示例展示了运行状况查抄终结点附加了授权计策。添加的授权计策是特别数据,也就是终结点元数据。
可以通过路由感知中间件来处理惩罚元数据。
元数据可以是任意的 .NET 范例。
上面提到元数据可以是人意的.NET范例,那么详细到底是什么呢?元数据如何利用呢?
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.Use(next => context => { var endpoint = context.GetEndpoint(); if (endpoint?.Metadata.GetMetadata<AuditPolicyAttribute>()?.NeedsAudit ==true) { Console.WriteLine("开始处理惩罚事务逻辑"); Console.WriteLine($"ACCESS TO SENSITIVE DATA AT: {DateTime.UtcNow}"); } return next(context); }); app.UseEndpoints(endpoints => { endpoints.MapGet("https://www.jb51.net/", async context => { await context.Response.WriteAsync("Hello world!"); }); // Using metadata to configure the audit policy. endpoints.MapGet("/sensitive", async context => { await context.Response.WriteAsync($"sensitive data{DateTime.UtcNow}"); }) .WithMetadata(new AuditPolicyAttribute(needsAudit: true)); }); } } public class AuditPolicyAttribute : Attribute { public AuditPolicyAttribute(bool needsAudit) { NeedsAudit = needsAudit; } public bool NeedsAudit { get; } }
看上面的示例中,在终结点绑定"/sensitive"的时候会附加元数据WithMetadata。当会见“/”的时候会输出"Hello world!"。可是在app.Use中并不会执行输出"处理惩罚事务逻辑",因为并没有匹配的元数据。可是当执行"/sensitive"的时候就会输出Console.WriteLine("开始处理惩罚事务逻辑");。因为在终结点界说的时候添加了元数据。元数据可以是人意.NET范例。上面的元数据也是我们自界说Class。
较量终端中间件和路由