I am trying to create a middleware that should execute after the execution of endpoint. But when I add middleware in after the app.UseEndPoints()
, it never gets invoked, however it is invoked if placed before app.UseEndPoints()
, but that invokes it before execution of endpoint.
I tried to create a middleware, I placed if after app.UseEndPoints()
middleware in the Configure
method in the Startup
class and expected it to be invoked after the execution of the endpoint (Web APIs action method), but it did not get invoked.
Middleware placed after app.UseEndpoints()
usually doesn't execute because of how the ASP.NET Core request handling pipeline works. When a request comes in, it moves through each piece of middleware in the order they were added to the pipeline until it reaches app.UseEndpoints()
. This particular middleware is responsible for matching the incoming request to a specific endpoint.
Once a matching endpoint is found, app.UseEndpoints()
invokes that endpoint to handle the request. After the endpoint finishes processing the request and generates a response, the response is sent back to the client immediately. This means the pipeline ends there, and any middleware added after app.UseEndpoints()
is not executed because the response has already been dealt with, and there's no further processing required or expected for that request.
To execute logic after an endpoint has processed a request, you can try any of the below option:
_next.Invoke(context)
within the middleware. This part of the code will run after the downstream middleware, including the endpoint that app.UseEndpoints()
invokes, has finished executing.Map
or MapWhen
.Below is the example how you can achieve requirement with custom middleware:
public class MyCustomMiddleware
{
private readonly RequestDelegate _next;
public MyCustomMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
// Any logic here runs before the rest of the pipeline, e.g., before an endpoint is executed.
await _next(context); // Call the next middleware in the pipeline.
// Any logic here runs after the rest of the pipeline.
// For instance, after the endpoint has executed and a response has been generated.
}
}
In your Startup
class’ Configure
method, you insert your middleware before app.UseEndpoints
:
public void Configure(IApplicationBuilder app)
{
// ...
// Add your middleware before UseEndpoints
app.UseMiddleware<MyCustomMiddleware>();
app.UseEndpoints(endpoints =>
{
// ...
});
// Don't add middleware here since it won't be executed normally after UseEndpoints
}
Here is the code with action filters:
For action filters, you can create a custom class that inherits from IActionFilter
or IAsyncResultFilter
and then register that filter globally or on specific controllers or actions:
public class MyCustomActionFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
// Logic before the action executes.
}
public void OnActionExecuted(ActionExecutedContext context)
{
// Logic after the action executes.
}
}
Then register the filter in Startup
(in ConfigureServices
method):
services.AddControllers(options =>
{
options.Filters.Add(new MyCustomActionFilter());
});