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