asp.net Understanding of MVC core pipeline and interceptor

Time:2020-8-9

Take a look today asp.net The execution pipeline of core. Take a look at the official instructions:

From the picture above, you can polish it, asp.net The execution order of the core is: when a request is received, the request will first pass through the registered middleware and then enter the interceptor pipeline of MVC

After entering the MVC pipeline, the filtering correction is performed according to the above sequence.

OK, according to the above instructions, we will create a new MVC demo and switch the execution mode to console operation


// 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");
 });
}

Implementation results:

Without much explanation, from here we can polish in accordance with the official documentation.

After looking at the execution sequence of middleware, let’s understand the usage and execution order of MVC interceptor.

According to the execution order of MVC filter pipeline, we will look at the following usage respectively:

1) Authorization filter: the interceptor has the highest priority. When a request enters the MVC, it will be verified by the authorization filter whether it has permission to access. If not, it will jump out.

Synchronous usage:


public class AuthorizationFilter: IAuthorizationFilter
{
 public void OnAuthorization(AuthorizationFilterContext context)
 {
  context.HttpContext.Response.WriteAsync("authorization filter \r");
 }
}

Asynchronous usage:


public class AsyncAuthorizationFilter: IAsyncAuthorizationFilter
{
 public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
 {
  await context.HttpContext.Response.WriteAsync($"async authorization filter in \r");
 }
}

2) Resourcefilter: the interceptor is used as the second interceptor,

Onresourceexecuting runs code before model binding. Onresourceexecuted runs the code after the rest of the pipeline completes.

Synchronous usage:


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");
 }
}

Asynchronous usage:


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: runs code immediately before and after the action method is called; you can change the parameters passed to the action; you can change the results returned from the action.

Synchronous usage:


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");
 }
}

Asynchronous usage:


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: applies variable policy to the exception handled by the declaration before writing anything to the response body.

Synchronous usage:


public class ExceptionFilter: IExceptionFilter
{
 public void OnException(ExceptionContext context)
 {
  context.HttpContext.Response.WriteAsync($"exception \r");
 }
}

Asynchronous usage:


public class AsyncExceptionFilter: IAsyncExceptionFilter
{
 public Task OnExceptionAsync(ExceptionContext context)
 {
  context.HttpContext.Response.WriteAsync($"exception async \r");
  return Task.CompletedTask;
 }
}

5) Resultfilter: runs the code immediately before and after the result of the operation; it runs only if the action method executes successfully. You can set the format to return the result:

Synchronous operation:


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");
 }
}

Asynchronous usage:


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");
 }
}

The registration method is to register by partition, which has been described above and will not be described any more. Let’s take a look at the operation (page output) below:

Define an exception and see the following results:


public IActionResult Privacy()
{
  throw new Exception("error");
}

OK, the goal is achieved. Let’s not say much. Next time, we’ll see the concrete implementation of the interceptor.

Reference documents: ASP.NET Filters in core

summary

This is about asp.net The article of MVC core pipeline and interceptor is introduced here, more relevant asp.net MVC core pipeline and interceptor content, please search the previous articles of developeppaer or continue to browse the related articles below. I hope you can support developeppaer more in the future!