I have an ASP.NET Core 6 MVC application with both view-based controllers and API controllers. I'd like to be able to disable certain controllers through configuration, and I have a middleware that works:
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
context.Request.RouteValues.TryGetValue("controller", out var controller);
if (controller != null)
{
if (!_allowControllers.IsMatch(controller as string))
context.Abort();
else if (_denyControllers.IsMatch(controller as string))
context.Abort();
}
await next(context);
}
However when triggered, the client gets a broken connection. Is it possible to return a "404" instead? I've tried
context.Response.Redirect("/notfound");
instead of Abort
, but it doesn't seem to work for the API controllers.
You want so called short-circuiting/terminal middleware i.e. one which does not invoke (or does not always invoke) next
. Something like the following:
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
context.Request.RouteValues.TryGetValue("controller", out var controller);
if (controller is string str
&& (!_allowControllers.IsMatch(str) || _denyControllers.IsMatch(str)))
{
context.Response.StatusCode = (int)HttpStatusCode.NotFound;
}
else
{
await next(context);
}
}
Read more: