Reputation: 3931
I have followed the following link;
Custom HttpResponseException Middleware Asp.Net Core 2.0
I now want to add a message to the body of the response to give context to the exception.
I modified the middleware Invoke method as follows;
public async Task Invoke(HttpContext context)
{
try
{
await _next(context);
}
catch (HttpStatusCodeException exception)
{
context.Response.StatusCode = (int)exception.StatusCode;
// byte[] data = Encoding.UTF8.GetBytes(exception.Message);
// await context.Response.Body.WriteAsync(data, 0, data.Length);
await context.Response.WriteAsync(exception.Message);
context.Response.Headers.Clear();
}
}
However when adding the WriteAsync line to the method I don't get a response from the Api (I am testing through postman).
Can anyone point me in the right direction as to what I am doing wrong here please?
Full code for the class and middleware are below;
namespace Services.WebApi.Middleware
{
public class HttpErrorHandlerMiddleware
{
private readonly RequestDelegate _next;
public HttpErrorHandlerMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
try
{
await _next(context);
}
catch (HttpStatusCodeException exception)
{
context.Response.StatusCode = (int)exception.StatusCode;
// byte[] data = Encoding.UTF8.GetBytes(exception.Message);
// await context.Response.Body.WriteAsync(data, 0, data.Length);
await context.Response.WriteAsync(exception.Message);
context.Response.Headers.Clear();
}
}
}
public static class HttpErrorHandlerMiddlewareExtensions
{
public static IApplicationBuilder UseHttpErrorHandlerMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<HttpErrorHandlerMiddleware>();
}
}
}
The HttpStatusCodeException class is as follows;
public class HttpStatusCodeException : Exception
{
public HttpStatusCode StatusCode { get; set; }
public HttpStatusCodeException(HttpStatusCode statusCode)
{
StatusCode = statusCode;
}
public HttpStatusCodeException(HttpStatusCode statusCode, string message) : base(message)
{
StatusCode = statusCode;
}
}
Upvotes: 2
Views: 1517
Reputation: 101443
This
await context.Response.WriteAsync(exception.Message);
context.Response.Headers.Clear();
Is not going to work, because after you sent the respose (via Response.WriteAsync
) - headers cannot be changed\cleared, because headers are sent before the response body, and so at this moment are already sent to client. Just change the order like this:
context.Response.Headers.Clear();
await context.Response.WriteAsync(exception.Message);
And it should work as expected. It also worth checking that response has not already started at this point:
if (!context.Response.HasStarted) {
context.Response.Headers.Clear();
await context.Response.WriteAsync(exception.Message);
}
Also ensure that you register your middleware before other middleware. Right:
app.UseHttpErrorHandlerMiddleware();
app.UseMvc();
Wrong
app.UseMvc();
app.UseHttpErrorHandlerMiddleware();
Upvotes: 2