What is the Difference Between Middleware and Filter ASP.NET Core

Middleware and Filter are extensively used in ASP.NET Core application and some of the tasks like Authenticating the incoming request, logging the request and response, etc. can be achieved both by Middleware and Filter so the question arises when we should go for Middleware and when to go for Filter.

Middleware can be used for the entire request pipeline but Filters is only used within the Routing Middleware where we have an MVC pipeline so Middleware operates at the level of ASP.NET Core but Filters executes only when requests come to the MVC pipeline.

Let’s understand the difference using the Code Example.

Let’s create a new ASP.Net Core Project using Visual Studio 2022 Community Edition.

Step 1: Open Visual Studio 2022 Community Edition which is free to use.

Step 2: Click on “Create a new project”.

Step 3: Select “ASP.NET Core Web API” from Project Templates and click on “Next”.

Step 4: Give a Project Name, Select the location and click on “Next”.

Step 5: Select Framework as .Net Core 3.1 or .Net 6.0 and if you want to send or receive a request over HTTPS then select the checkbox “Configure for Https” otherwise uncheck the same.

Step 6: If want a default Docker set up for your application then check the “Enable Docker” as well and then click on “Create”.

Please Note I have selected .Net Core 3.1 as the Framework and the code examples given below are done in .Net Core 3.1 so there will be some code changes or structure changes if you select .Net 6.0

First, we will create a sample middleware that will log information and pass the request to the next available middleware.

Sample Middleware

public class SampleMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<SampleMiddleware> _logger;
    public SampleMiddleware(RequestDelegate next, ILogger<SampleMiddleware> logger)
    {
        _next = next ?? throw new ArgumentNullException(nameof(next));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }
    public async Task Invoke(HttpContext httpContext)
    {
        _logger.LogInformation("Before Sample Middleware");
        await _next(httpContext);
        _logger.LogInformation("After Sample Middleware");
    }
}

Now we have to configure the middleware in Configure method of the Startup.cs file

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    app.UseRouting();
    app.UseAuthorization();
    app.UseMiddleware<SampleMiddleware>(); // Configuring the Sample Middleware
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

Similarly, we will create a sample Filter as well where we will be logging information.

public class SampleActionFilter : IActionFilter
{
    private readonly ILogger<SampleActionFilter> _logger;
    public SampleActionFilter(ILogger<SampleActionFilter> logger)
    {
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }
    public void OnActionExecuted(ActionExecutedContext context)
    {
        _logger.LogInformation($"From OnActionExecuted method of {nameof(SampleActionFilter)}");
    }
    public void OnActionExecuting(ActionExecutingContext context)
    { 
        _logger.LogInformation($"From OnActionExecuting method of {nameof(SampleActionFilter)}");
    }
}

Now we have to configure the Filter as well in the Application so let’s do the same at the Controller level using TypeFilter Attribute.

[ApiController]
[Route("[controller]")]
[TypeFilter(typeof(SampleActionFilter))]
public class WeatherForecastController : ControllerBase
{
}

Now we will also log in to the default action of the Controller.

[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
    _logger.LogInformation($"From Action Method of {nameof(WeatherForecastController)}");
    var rng = new Random();
    return Enumerable.Range(1, 5).Select(index => new WeatherForecast
    {
        Date = DateTime.Now.AddDays(index),
        TemperatureC = rng.Next(-20, 55),
        Summary = Summaries[rng.Next(Summaries.Length)]
    })
    .ToArray();
}

If we run the application now, we can see all the logs in Command Prompt.

info: DotnetCore3._1SampleWebApi.Middlewares.SampleMiddleware[0]
      Before Sample Middleware
info: DotnetCore3._1SampleWebApi.Filters.SampleActionFilter[0]
      From OnActionExecuting method of SampleActionFilter
info: DotnetCore3._1SampleWebApi.Controllers.WeatherForecastController[0]
      From Action Method of WeatherForecastController
info: DotnetCore3._1SampleWebApi.Filters.SampleActionFilter[0]
      From OnActionExecuted method of SampleActionFilter
info: DotnetCore3._1SampleWebApi.Middlewares.SampleMiddleware[0]
      After Sample Middleware

As we can see from the above output first request comes to Middleware, and then it passes the request to Filter Finally, it goes to Controller Action Method therefore following is the pictorial flow of an HTTP Request coming to ASP.NET Core application.

Differences between Middleware and Filter

  • Middleware has access to HttpContext but Filter has access to wider MVC Context which helps us to access routing data and model binding information.
  • Filters are only part of MVC Middleware but middlewares are part of every request pipeline.
  • The Execution of Middleware occurs before MVC Context becomes available in the pipeline.
  • Middleware will be executed irrespective of the Controller or Action Method we are hitting but Filters will be executed based on which Controller or Action Method it has been configured.

Below is the screenshot of the Filter and we can see from the intelli-sense that the ActionExecutedContext has access to all the information like HttpContext, ModelState, RouteData, etc…

Similarities between Middleware and Filter

  • Both Middleware and Filters help us to achieve cross-cutting concerns like logging, exception handling or performance profiling, etc.…
  • Both Middleware and Filter can short circuit the request by returning directly the response without executing the Controller Action Method. For Example, if we are authenticating and it fails then we can short circuit the request.

Conclusion

Middleware and Filters both are designed to handle cross-cutting concerns of the application and we should choose either of them wisely therefore if we want to access only HttpContext then we can go for Middleware and suppose if want to access MVC Context like Routing data or Model Binding then MVC will be preferred over Middleware.

Get your ASP.NET hosting as low as $1.00/month with ASPHostPortal. Our fully featured hosting already includes

  • Easy setup
  • 24/7/365 technical support
  • Top level speed and security
  • Super cache server performance to increase your website speed
  • Top 9 data centers across the world that you can choose.

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *