2

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;
    }

}
1
  • Hope this link will help you to some extent Commented Mar 15, 2018 at 7:37

1 Answer 1

2

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();
Sign up to request clarification or add additional context in comments.

1 Comment

worked perfectly, thank you for your help on this and the last question. I'd also like to say your explanations are also tip top and explain the situation well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.