今天来看一下asp.net core的执行管道。先看下官方说明:
从上图可以抛光,asp.net core的执行顺序是,当收到一个请求后,request请求会先经过已注册的中间件,然后会进入到mvc的拦截器管道:
进入mvc管道后,根据以上顺序执行过滤校正。
OK,根据以上说明下面我们新建一个MVC的演示,将执行方式切换为控台运行:
// This method gets called by the runtime. Use this method to add services to the container.public void ConfigureServices(IServiceCollection services){services.AddControllersWithViews(config=>{Console.WriteLine(\"execute C\");//config.Filters.Add(new AsyncAuthorizationFilter());config.Filters.Add(new AuthorizationFilter());config.Filters.Add(new ResourceFilter());//config.Filters.Add(new AsyncResourceFilter());config.Filters.Add(new ActionFilter());//config.Filters.Add(new AsyncActionFilter());config.Filters.Add(new ResultFilter());//config.Filters.Add(new AsyncResultFilter());config.Filters.Add(new ExceptionFilter());//config.Filters.Add(new AsyncExceptionFilter());Console.WriteLine(\"execute D\");});services.AddSession(config=> {Console.WriteLine(\"execute E\");});}// 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();}else{app.UseExceptionHandler(\"/Home/Error\");}app.UseStaticFiles();app.UseRouting();app.UseAuthorization();app.Use(async (context, next) =>{Console.WriteLine(\"execute F\");await context.Response.WriteAsync(\"hello world\");Console.WriteLine(\"execute G\");});//app.UseSession();app.UseEndpoints(endpoints =>{Console.WriteLine(\"execute A\");endpoints.MapControllerRoute(name: \"default\",pattern: \"{controller=Home}/{action=Index}/{id?}\");Console.WriteLine(\"execute B\");});}
执行结果:
不多做解释,从从这里我们可以抛光符合官方说明文档。
看完中间件执行顺序,下面我们来了解下mvc拦截器的使用与执行顺序。
根据mvc filter管道执行顺序,我们分别来看下用法:
1)AuthorizationFilter:该拦截器是优先级最高的,当请求进入mvc后,首先会被AuthorizationFilter验证是否有权限访问,无权限则跳出。
同步用法:
public class AuthorizationFilter: IAuthorizationFilter{public void OnAuthorization(AuthorizationFilterContext context){context.HttpContext.Response.WriteAsync(\"authorization filter \\r\");}}
异步用法:
public class AsyncAuthorizationFilter: IAsyncAuthorizationFilter{public async Task OnAuthorizationAsync(AuthorizationFilterContext context){await context.HttpContext.Response.WriteAsync($\"async authorization filter in \\r\");}}
2)ResourceFilter:该拦截器是作为第二道拦截器,
OnResourceExecuting在模型绑定之前运行代码。OnResourceExecuted在管道的其余阶段完成之后运行代码。
同步用法:
public class ResourceFilter: IResourceFilter{public void OnResourceExecuting(ResourceExecutingContext context){context.HttpContext.Response.WriteAsync($\"resource executing\\r\");}public void OnResourceExecuted(ResourceExecutedContext context){context.HttpContext.Response.WriteAsync($\"resource executed \\r\");}}
异步用法:
public class AsyncResourceFilter: IAsyncResourceFilter{public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next){await context.HttpContext.Response.WriteAsync($\" async resource filter in. \\r\\n\");await next();await context.HttpContext.Response.WriteAsync($\"async resource filter out. \\r\\n\");}}
3)ActionFilter:在调用操作方法之前和之后立即运行代码;可以更改传递到操作中的参数;可以更改从操作返回的结果。
同步用法:
public class ActionFilter: IActionFilter{public void OnActionExecuting(ActionExecutingContext context){context.HttpContext.Response.WriteAsync($\"action executing \\r\");}public void OnActionExecuted(ActionExecutedContext context){context.HttpContext.Response.WriteAsync($\"action executed . \\r\");}}
异步用法:
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next){await context.HttpContext.Response.WriteAsync($\"async action execution in. \\r\\n\");await next();await context.HttpContext.Response.WriteAsync($\"async action execution out. \\r\\n\");}
4)OnException:在向响应正文写入任何内容之前,对声明处理的异常应用变量策略。
同步用法:
public class ExceptionFilter: IExceptionFilter{public void OnException(ExceptionContext context){context.HttpContext.Response.WriteAsync($\"exception \\r\");}}
异步用法:
public class AsyncExceptionFilter: IAsyncExceptionFilter{public Task OnExceptionAsync(ExceptionContext context){context.HttpContext.Response.WriteAsync($\"exception async \\r\");return Task.CompletedTask;}}
5)ResultFilter:在执行操作结果之前和之后立即运行代码;仅当操作方法成功执行时,其才会运行。可以设置格式化返回结果:
同步操作:
public class ResultFilter: IResultFilter{public void OnResultExecuting(ResultExecutingContext context){context.HttpContext.Response.WriteAsync($\"result executing\\r\");}public void OnResultExecuted(ResultExecutedContext context){context.HttpContext.Response.WriteAsync($\"result executed \\r\");}}
异步用法:
public class AsyncResultFilter: IAsyncResultFilter{public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next){await context.HttpContext.Response.WriteAsync($\"result execution async in \\r\");await next();await context.HttpContext.Response.WriteAsync($\"result execution async out. \\r\");}}
注册方式我们就是用分区注册,已经在上面说明,不再多做表述,下面我们看下运行情况(页面输出):
定义一个异常看下结果:
public IActionResult Privacy(){throw new Exception(\"error\");}
ok,目标达成,不多说了,下次再看拦截器具体实现。
参考文档:ASP.NET Core 中的筛选器
原创,转载注明出处。