Reputation: 7961
I am migrating a Web API 2 application over to MVC 6 and I'm struggling to figure out how to return a custom response when status codes like 404 or 405 occur. In Web API, I used an HttpMessageHandler
for 404 and a DelegatingHandler
for 405.
I am aware of the concept of middleware, but it seems like the middleware isn't executing late enough in the pipeline to capture the 404. Also, generating responses in middleware is sub-optimal because the HttpResponse
class only exposes raw HTTP parameters like ContentLength
and Body
. I would prefer to simply return an IActionResult
that contains a custom response model like all my regular endpoints do.
Startup code:
applicationBuilder.UseMiddleware<NotFoundMiddleware>();
applicationBuilder.UseMvc();
Middleware:
public class NotFoundMiddleware
{
private readonly RequestDelegate _next;
public NotFoundMiddleware(RequestDelegate next)
{
_next = next.EnsureNotNull(nameof(next));
}
public Task Invoke(HttpContext context)
{
if (context.Response?.StatusCode == StatusCodes.Status404NotFound)
{
// context.Response.StatusCode is 200 because context.Response is set to an instance of DefaultHttpResponse
}
return _next.Invoke(context);
}
}
Is there a good way of accomplishing what I need?
Upvotes: 1
Views: 86
Reputation: 247641
Rearrange how you are executing your logic
public class NotFoundMiddleware {
private readonly RequestDelegate _next;
public NotFoundMiddleware(RequestDelegate next) {
_next = next.EnsureNotNull(nameof(next));
}
public async Task Invoke(HttpContext context) {
//let the context go through the pipeline
await _next.Invoke(context);
if (context.Response?.StatusCode == StatusCodes.Status404NotFound) {
//execute your logic on the way out of the pipeline.
}
}
}
and also make sure that you register it early in the pipeline
Upvotes: 2