IAsyncActionFilter
我在使用 .Net Core实现的类中有以下代码。
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
await next.Invoke();
using (var reader = new StreamReader(context.HttpContext.Response.Body))
{
var responseBodyText = await reader.ReadToEndAsync();
var messageObjToLog = new
{
responseBody = responseBodyText,
statusCode = context.HttpContext.Response.StatusCode
};
_logger.LogInformation(JsonConvert.SerializeObject(messageObjToLog));
context.HttpContext.Response.Body.Seek(0, SeekOrigin.Begin);
}
}
这一行:
using (var reader = new StreamReader(context.HttpContext.Response.Body))
产生以下错误
失败:Microsoft.AspNetCore.Server.Kestrel[13]
连接 ID“0HLFBE2K7NSD3”,请求 ID“0HLFBE2K7NSD3:00000001”:应用程序引发了未处理的异常。System.ArgumentException:流不可读。在 System.IO.StreamReader..ctor(Stream stream, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize, Boolean leaveOpen) 在 System.IO.StreamReader..ctor(Stream stream) 在 Adapter.Logging.Middleware.LogResponseFilter.d__2.MoveNext () 在 C:\src\Adapter\Logging\Middleware\LogRequestResponseFilter.cs:line 56
--- 从先前引发异常的位置结束堆栈跟踪 --- 在 Microsoft.AspNetCore.Mvc 的 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 的 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()。 Internal.ControllerActionInvoker.d__10.MoveNext()
--- 从先前引发异常的位置结束堆栈跟踪 --- 在 Microsoft.AspNetCore 的 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context) 的 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()。 Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) 在 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__14.MoveNext()
--- 从先前引发异常的位置结束堆栈跟踪 --- 在 Microsoft.AspNetCore.Mvc 的 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 的 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()。 Internal.ResourceInvoker.d__22.MoveNext()
--- 从先前引发异常的位置结束堆栈跟踪 --- 在 Microsoft.AspNetCore 的 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context) 的 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()。 Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) 在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.d__17.MoveNext()
--- 从先前引发异常的位置结束堆栈跟踪 --- 在 Microsoft.AspNetCore.Mvc 的 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 的 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()。 Internal.ResourceInvoker.d__15.MoveNext()
--- 从先前引发异常的位置结束堆栈跟踪 --- 在 Microsoft.AspNetCore.Builder 的 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 的 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()。 RouterMiddleware.d__4.MoveNext()
--- 从先前引发异常的位置结束堆栈跟踪 --- 在 Microsoft.AspNetCore.Cors 的 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 的 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()。 Infrastructure.CorsMiddleware.d__7.MoveNext() --- 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task任务)在 Microsoft.AspNetCore.Hosting.Internal.RequestServicesContainerMiddleware.d__3.MoveNext() --- 从先前引发异常的位置结束堆栈跟踪---在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 在 System.运行。Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Frame`1.d__2.MoveNext() 上的 CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)
我的问题是:
为了安全地重置响应流,我需要做什么?
我有另一个用于记录的 IAsyncActionFilter 实现:
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
using (var reader = new StreamReader(context.HttpContext.Request.Body))
{
var requestBodyText = await reader.ReadToEndAsync();
context.HttpContext.Request.EnableRewind();
context.HttpContext.Request.Body.Seek(0, SeekOrigin.Begin);
var messageObjToLog = new
{
scheme = context.HttpContext.Request.Scheme,
host = context.HttpContext.Request.Host,
path = context.HttpContext.Request.Path,
queryString = context.HttpContext.Request.Query,
requestBody = requestBodyText
};
_logger.LogInformation(JsonConvert.SerializeObject(messageObjToLog));
}
await next.Invoke();
}