2

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();
    }
4

1 回答 1

0

大概放“await next.Invoke();” 在方法结束时。

于 2018-07-17T02:25:57.037 回答