Регистрация тел ответа в фильтрах действий

У меня есть следующий код в классе, который реализует 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]

Идентификатор соединения «0HLFBE2K7NSD3», идентификатор запроса «0HLFBE2K7NSD3: 00000001»: приложение сгенерировало необработанное исключение. System.ArgumentException: поток не читался. в System.IO.StreamReader..ctor (поток потока, кодирование кодирования, логическое значение detectEncodingFromByteOrderMarks, Int32 bufferSize, логическое значение leaveOpen) в System.IO.StreamReader..ctor (поток потока) в Adaptor.Logging.Middleware.LogResponseFilter.d__2.MoveNe () в C: \ src \ Adapter \ Logging \ Middleware \ LogRequestResponseFilter.cs: строка 56

--- Конец трассировки стека из предыдущего места, где было создано исключение --- в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (задача задачи) в Microsoft.AspNetCore.Mvc. Internal.ControllerActionInvoker.d__10.MoveNext ()

--- Конец трассировки стека из предыдущего места, где было создано исключение --- в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () в Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow (контекст ActionExecutedContext) в Microsoft.AspNetCore. Mvc.Internal.ControllerActionInvoker.Next (Состояние и следующий, Область и область, Объект и состояние, Логическое значение и isCompleted) в Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__14.MoveNext ()

--- Конец трассировки стека из предыдущего места, где было создано исключение --- в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (задача задачи) в Microsoft.AspNetCore.Mvc. Internal.ResourceInvoker.d__22.MoveNext ()

--- Конец трассировки стека из предыдущего места, в котором возникло исключение --- в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () в Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow (контекст ResourceExecutedContext) в Microsoft.AspNetCore. Mvc.Internal.ResourceInvoker.Next (состояние и следующий, область и область действия, объект и состояние, логическое значение и isCompleted) в Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.d__17.MoveNext ()

--- Конец трассировки стека из предыдущего места, где было создано исключение --- в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (задача задачи) в Microsoft.AspNetCore.Mvc. Internal.ResourceInvoker.d__15.MoveNext ()

--- Конец трассировки стека из предыдущего места, в котором возникло исключение --- в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (задача задачи) в Microsoft.AspNetCore.Builder. RouterMiddleware.d__4.MoveNext ()

--- Конец трассировки стека из предыдущего места, в котором возникло исключение --- в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (задача задачи) в Microsoft.AspNetCore.Cors. Infrastructure.CorsMiddleware.d__7.MoveNext () --- Конец трассировки стека из предыдущего места, где было сгенерировано исключение --- в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (TaskAndDebuggerNotification (TaskAndDebuggerNotification) задача) в Microsoft.AspNetCore.Hosting.Internal.RequestServicesContainerMiddleware.d__3.MoveNext () --- Конец трассировки стека из предыдущего места, где было сгенерировано исключение --- в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () в System. Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (задача задачи) в Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Ht tp.Frame`1.d__2.MoveNext ()

У меня вопрос:

Что мне нужно сделать, чтобы безопасно сбросить поток ответов?

У меня есть еще одна реализация 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();
    }

person user3060716    schedule 16.07.2018    source источник
comment
Вам следует сделать свой пост более подробным и переформатировать сообщение об ошибке.   -  person 0xCursor    schedule 17.07.2018
comment
Возможно, вместо этого попробуйте фильтры результатов.   -  person Mark G    schedule 17.07.2018


Ответы (1)


Вероятно, поставьте "await next.Invoke ();" в конце метода.

person Dave C    schedule 17.07.2018