Search code examples
.net-coreminimal-apis

How to fire a function on every request in ASP.NET Core Minimal API


Just starting out with ASP.NET Core Minimal API and trying to solve all the little issues that will have to work before it's usable in my situation.

This API will be accessible from multiple tenants, so I need to check the calling domain on every request (including when authenticating via user/pass) and then set some variables that need to be accessible from all routes.

Can anyone point me in the right direction because I can't find any information on how this is achieved.

Thanks

UPDATE: some examples of where the middleware works and doesn't...

So this is the middleware:

app.Use((context, next) =>
{
    // Lets assume the domain info is in the query string
    context.Items["domain"] = context.Request.Query["domain"];
    return next();
});

And this code works just fine

app.MapGet("/", async handler =>
{
    // Get the domain and then return back the formatted string with the domain name
    var domain = handler.Items["domain"];
    await handler.Response.WriteAsJsonAsync($"Hello World! {domain}");
});

When I have an endpoint decorated with [AlowAnonymous], I have to put handler in brackets like this

app.MapGet("/whatever",
[AllowAnonymous] async (handler)  =>
{
    // Get the domain and then return back the formatted string with the domain name
    var domain = handler.Items["domain"];
    await handler.Response.WriteAsJsonAsync($"Hello World! {domain}");
});

If I have multiple class objects it borks (this has the HttpRequest, my db class and a login class). The error is

Delegate 'RequestDelegate' does not take 4 arguments.

app.MapGet("/whatever2",
[AllowAnonymous] async (handler, HttpRequest request, SqlConnection db, Login login) =>
{
    // Get the domain and then return back the formatted string with the domain name
    var domain = handler.Items["domain"];
    await handler.Response.WriteAsJsonAsync($"Hello World! {domain}");
}); 

Thanks


Solution

  • You can add a piece of middleware in the request pipeline to fetch any details needed for mapped APIs. For example...

    var builder = WebApplication.CreateBuilder(args);
    
    var app = builder.Build();
    
    app.Use((context, next) =>
    {
        // Lets assume the domain info is in the query string
        context.Items["domain"] = context.Request.Query["domain"];
        
        return next();
    });
    
    app.MapGet("/", async handler =>
    {
        // Get the domain and then return back the formatted string with the domain name
        var domain = handler.Items["domain"];
        await handler.Response.WriteAsJsonAsync($"Hello World! {domain}");
    });
    
    app.Run();
    

    The above adds middleware that runs first before attempting to map to any of the endpoints.