Related: Modify static file response in ASP.NET Core
However, I do not understand why the following code works when my business logic throws one of my custom exceptions like UnprocessableException:
try { await next.Invoke(context); } catch (UnprocessableException uex) { Logger.Warn(uex); context.Response.StatusCode = 422; var responseContent = JsonConvert.SerializeObject(new { uex.Message }); await context.Response.WriteAsync(responseContent); } // more specific exceptions resulting in HTTP 4xx status but when a totally unexpected IndexOutOfRangeException is caught by the last catch block in the chain
catch (Exception ex) { Logger.Error(ex); context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; var responseContent = env.IsDevelopment() ? JsonConvert.SerializeObject(new { ex.Message, ex.StackTrace }) : JsonConvert.SerializeObject(new { Message = "An internal error occured" }); await context.Response.WriteAsync(responseContent); } this exception is thrown when trying to set the status code:
System.InvalidOperationException: StatusCode cannot be set, response has already started. bei Microsoft.AspNetCore.Server.Kestrel.Internal.Http.Frame.ThrowResponseAlreadyStartedException(String value) bei Microsoft.AspNetCore.Server.Kestrel.Internal.Http.Frame.set_StatusCode(Int32 value) bei Microsoft.AspNetCore.Server.Kestrel.Internal.Http.Frame.Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.set_StatusCode(Int32 value) bei Microsoft.AspNetCore.Http.Internal.DefaultHttpResponse.set_StatusCode(Int32 value) bei Anicors.Infrastructure.Middlewares.ScopeMiddleware.<Invoke>d__5.MoveNext()