Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I need to run two middlewares for all my endpoints but the ones under /accounts/*.

I use this in ConfigureServices:

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddControllers();
}

and the configure method looks like:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IUserService  userService)
{
    app.UseCors(builder => builder
        //.AllowAnyOrigin()
        .SetIsOriginAllowed((host) => true)
        .AllowAnyMethod()
        .AllowAnyHeader()
        .AllowCredentials());

    app.UseRouting();

    app.UseAuthentication();

    //THIS IS WHAT I JUST ADDED TO SUPPORT THE BRANCHING OF ROUTES
    app.MapWhen(context =>
    {
        return !context.Request.Path.StartsWithSegments("/accounts");
    }, appBuilder =>
    {
        appBuilder.UseMiddleware<TenantProviderMiddleware>();
        appBuilder.UseMiddleware<UserClaimsBuilderMiddleware>();
    });

    //app.UseMiddleware<TenantProviderMiddleware>();
    //app.UseMiddleware<UserClaimsBuilderMiddleware>();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHub<VehicleHub>("/vehicle-hub");
        endpoints.MapControllers();
    });

 }

But I'm getting the following error:

System.InvalidOperationException: The request reached the end of the pipeline without executing the endpoint: 'WebAPI.Controllers.VehiclesController.Get (WebApi)'. Please register the EndpointMiddleware using 'IApplicationBuilder.UseEndpoints(...)' if using routing.

From the error I understand that I should be using UseEndpoints instead of UseMiddleware in the MapWhen method but can't get it right.

How should I register the middlewares then?

like image 413
Notbad Avatar asked Apr 19 '20 17:04

Notbad


People also ask

How to branch the middleware pipeline using map and mapwhen methods?

To branch the middleware pipeline, we can use both Map and MapWhen methods. The Map method is an extension method that accepts a path string as one of the parameters: When we provide the pathMatch string, the Map method will compare it to the start of the request path.

How to implement a middleware that needs to work on a route?

NET Core 3.0 If you have a Middleware that needs to work on a specific path, you should implement it by mapping it to a route in ASP.NET Core 3.0, instead of just checking the path names. This post doesn't handle regular Middlewares, which need to work all request, or all requests inside a Map or MapWhen branch.

How do I pass a request from one middleware component to another?

Pass the request to the next middleware component in the pipeline and also It can execute some work before and after the next component in the pipeline To build a pipeline, we are using request delegates, which handle each HTTP request. To configure request delegates, we use the Run, Map, and Use extension methods.

How to implement Middleware using endpoint routing in ASP NET Core?

Implement Middlewares using Endpoint Routing in ASP. NET Core 3.0 If you have a Middleware that needs to work on a specific path, you should implement it by mapping it to a route in ASP.NET Core 3.0, instead of just checking the path names.


1 Answers

It looks like you need UseWhen, which, according to the docs:

...branches the request pipeline based on the result of the given predicate. Unlike with MapWhen, this branch is rejoined to the main pipeline if it doesn't short-circuit or contain a terminal middleware

Because you're using MapWhen, both UseAuthorization and UseEndpoints have no affect for your /accounts/ paths. The error you've shown is because the Endpoints middleware doesn't run in this scenario.

like image 89
Kirk Larkin Avatar answered Sep 28 '22 02:09

Kirk Larkin