ProblemDetails middleware when Response has started
See original GitHub issueHi @khellang
I have one scenario that I would like to support with ProblemDetails. I usually create a unit of work middleware to make request transactional and consistent:
public class UnitOfWorkMiddleware
{
private readonly RequestDelegate next;
public UnitOfWorkMiddleware(RequestDelegate next)
{
this.next = next;
}
public async Task Invoke(HttpContext context)
{
await next(context);
var requestMethod = context.Request.Method;
var isSafeMethod = requestMethod == HttpMethods.Get || requestMethod == HttpMethods.Head;
var dbContext = context.RequestServices.GetService(typeof(EFDbContext)) as EFDbContext;
if (IsSuccessStatusCode(context.Response) && !isSafeMethod)
{
await dbContext.SaveChangesAsync();
}
}
private bool IsSuccessStatusCode(HttpResponse response)
{
return response.StatusCode >= 200 && response.StatusCode <= 299;
}
}
In case that SaveChanges() fail, problems details detect the exception but the response has started and rethrow the exception, but in this case I would like to continue using Problem Details.
One question related with this line https://github.com/khellang/Middleware/blob/4ff1f88d86573be0545ee40f60f01362568742b6/src/ProblemDetails/ProblemDetailsMiddleware.cs#L84
Why check if response has been started and not catch all exceptions? Can you tell me some scenario when you have to re throw the exception and not send a problems details to the client?
Actually I don’t know to manage my scenario in the right way.
Regards!
Issue Analytics
- State:
- Created 5 years ago
- Comments:6 (4 by maintainers)
Hmm, yeah, the problem seems to be that the
DbContext
has been disposed by the time theOnStarting
callback is invoked.Do you really need this to be custom middleware? I think it would be much easier if this was part of the MVC filter pipeline instead. That would let you save your changes before the result is written to the response body, without callback gymnastics.
Because the whole point of the middleware is to send an RFC7807 response to the client. If the response has already started, it’s too late for the middleware to do anything. That’s why it logs and rethrows the exception, in case anyone else is interested in it, like some other error handler or logging middleware.