Difference Between Middleware and Filter in Dotnet 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.


I have already written a detailed article for both Middleware and Filter so you can check that using the following link.


Middleware in Dotnet Core

Filters in Dotnet core


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.


request_flow_aspnet_core.png



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...

mvc_context_in_dotnet_core.png

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.


Share This Post

Linkedin
Fb Share
Twitter Share
Reddit Share

Support Me

Buy Me A Coffee