Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use Middleware for some controllers

In my ASP Net Core application I need to apply a custom Middleware only for specific controller.

I found this example

app.UseWhen(context => context.Request.Path.StartsWithSegments("/api"), appBuilder =>
{
    app.UseMiddleware();
});

Is this the correct way?

And how can I check if the request path Contains a specific path instead of starts with?

like image 552
skysurfer Avatar asked May 11 '26 01:05

skysurfer


2 Answers

(you are) "close" ... but with a few tweaks.. you can accomplish what you want:

You have

 app.UseMiddleware();

You most likely want to specify ~which middleware to use. See "MyMiddlewareOne" example below.

Below is tested with Asp.Net Core 3.1. ( I think I was at 3.1.407, but 3.1 or above should be ok )

simple version:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;


public class Startup
{

    public void Configure(ILogger<Startup> logger, IApplicationBuilder app, IWebHostEnvironment env)

    {


        app.UseRouting();

        app.UseAuthentication();


        app.UseWhen(context => context.Request.Path.StartsWithSegments("/api"), appBuilder =>
        {
            appBuilder.UseMiddleware<MyMiddlewareOne>();
        });

        app.UseEndpoints(endpoints =>
        { blah blah blah } );



    }
}

Now, you should be careful on how complex you make the rules.

But you can do something like this:

[ApiController]
[Route("apiwideopen/[controller]")]
public class WeatherForecastController : ControllerBase
{
}

[Route("apisecure/[controller]")]
[ApiController]
public class MyNeedsToBeSecureController : ControllerBase
{
}



        app.UseWhen(context => context.Request.Path.StartsWithSegments("/apisecure"), appBuilder =>
        {
            appBuilder.UseMiddleware<MyMiddlewareOne>();
        });

You can also do this to encapsulate rules.

        app.UseWhen(context => this.CheckMoreAdvancedRules(context), appBuilder =>
        {
            appBuilder.UseMiddleware<MyMiddlewareOne>();
        });



    private bool CheckMoreAdvancedRules(Microsoft.AspNetCore.Http.HttpContext ctx)
    {
        bool returnValue = false;

        if (null != ctx && ctx.Request.Path.StartsWithSegments("/apisecure"))
        {
            returnValue = true;
        }

        if(!returnValue)
        {
            /* do whatever you want here */
            /* if the moon is blue at midnight (then) returnValue = true; */
        }

        return returnValue;
    }

Lastly, you want to pay attention between

"MapWhen" and "UseWhen"

See:

Registering a middleware while using MapWhen for branching to run it just for a set of endpoints

also see this article:

https://www.devtrends.co.uk/blog/conditional-middleware-based-on-request-in-asp.net-core

like image 139
granadaCoder Avatar answered May 13 '26 15:05

granadaCoder


As this answer suggests if you require context of MVC you should prefer filters to middleware.

Also here you can find and example how to apply filters to the specific controller.

like image 45
Bohdan Stupak Avatar answered May 13 '26 17:05

Bohdan Stupak



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!