UseExceptionHandling在stream.CopyToAsync()调用后失败



我在。net Core 3.1中遇到UseExceptionHandler的问题,WebApi开始在将响应体复制到流后无法触发。我正在使用中间件来拦截webapi项目的传入请求和传出响应,并将日志记录记录到表中。在stream.CopyToAsync()方法被调用之前,它可以正常工作。在此之后的任何异常都不会触发ExceptionHandler,即使本地try/catch仍然会捕获异常,并且在catch块中重新抛出异常仍然不会触发ExceptionHandler。

调用方法
public async Task Invoke(HttpContext context)
{   
Stream originalBody = context.Response.Body;
try
{

using var memStream = new MemoryStream();
context.Response.Body = memStream;
await _next(context).ConfigureAwait(false);
await LogResponse(context, originalBody, memStream).ConfigureAwait(false);

}
catch (Exception ex)
{
throw ex; 
}
finally
{
context.Response.Body = originalBody;
originalBody.Close();                    
}
}
}

LogResponse方法
private async Task LogResponse(HttpContext context, Stream originalBody, MemoryStream stream)
{
stream.Seek(0, SeekOrigin.Begin);
string body = await new StreamReader(stream).ReadToEndAsync().ConfigureAwait(false);
stream.Seek(0, SeekOrigin.Begin);

//This is the line of code that breaks UseExceptionHandling pipeline
await stream.CopyToAsync(originalBody).ConfigureAwait(false);
var resp = new ApiLogItemRequest()
{
AppName = "AppName",
CreatedBy = "AppName",
DateTime = DateTime.Now,                
RawBodyJson = body,
TraceIdentifier = context.TraceIdentifier
};
await _logHelper.LogRawHttpBodyItem(resp);
}

任何想法或提示将不胜感激。谢谢!

我能找出问题所在。originalBody变量为空,然后ExceptionHandler抛出一个异常,在中间件中创建一个奇怪的错误循环,导致它无法执行处理程序的代码。我假设它与从CopyToAsync()行代码中使用空响应编写的上下文有关,但我不能100%确定原因。

我更改了代码,使其仅在originalBody不为空时进行复制,并且它修复了这个问题。

我在调试控制台中识别出ExceptionHandler挂机。ExceptionMiddlewareInvoke只应该被调用一次,但随后是HandleException,然后是Invoke,这使我认为ExceptionHandler中有一些例外,导致它跳过那里的代码。

(我最初没有说明,但根本问题是originalBody = context.Response.Body在之前写了_next(context);在这种情况下,没有响应体可以复制。这个逻辑应该出现在_next(context)

之后
System.Exception: Test exception
at Project.Api.Middleware.ApiRequestResponseLog.Invoke(HttpContext context) in C:GITProjectProject.ApiMiddlewareApiRequestResponseLog.cs:line 82
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)
//These below shouldn't have occured
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.HandleException(HttpContext context, ExceptionDispatchInfo edi)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)
at Microsoft.AspNetCore.Server.IIS.Core.IISHttpContextOfT`1.ProcessRequestAsync()

相关内容

  • 没有找到相关文章

最新更新