19

I have a middleware, which hides exception from client and returns 500 error in case of any exception:

public class ExceptionHandlingMiddleware
{
    private readonly RequestDelegate _next;

    public ExceptionHandlingMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        try
        {
            await _next.Invoke(context);
        }
        catch (Exception exception)
        {
            var message = "Exception during processing request";
            using (var writer = new StreamWriter(context.Response.Body))
            {
                context.Response.StatusCode = 500; //works as it should, response status 500
                await writer.WriteAsync(message);
                context.Response.StatusCode = 500; //response status 200
            }
        }
    }
}

My problem is that, if I set response status before writing body, client will see this status, but if I set status after writing message to body, client will receive response with status 200.

Could somebody explain me why it's happening?

P.S. I am using ASP.NET Core 1.1

Uriil
  • 11,948
  • 11
  • 47
  • 68

1 Answers1

17

That's by design, when you know how HTTP works.

Headers are in the beginning of the datastream (see wiki example). Once you send the data, you can't change/modify the headers, because the data has already been sent over the wire.

You would have to buffer the whole response if you want to set it later on, but this increases the memory usage. Here is a sample on how to swap the stream for a memory stream.

Chronicler
  • 45
  • 4
Tseng
  • 61,549
  • 15
  • 193
  • 205