Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.Net Core middleware cannot set status code on exception because "response has already started"

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() 
like image 598
Marc Wittke Avatar asked Aug 14 '17 12:08

Marc Wittke


1 Answers

Since this is the top search result on Google, I might as well tell new comers how I came up with this error. I was trying to use this answer by zipping files and downloading them (streaming) to the client. I returned return Ok() at the end of the actual controller action. I needed to return return new EmptyResult()

like image 60
CularBytes Avatar answered Sep 18 '22 14:09

CularBytes