Основное тело запроса контекста ActionFilter в Asp.Net расположено - PullRequest
0 голосов
/ 12 сентября 2018

У меня есть основной веб-API-проект asp.net, в котором я создал фильтр действий, чтобы регистрировать все вызовы, сделанные к API-интерфейсу

public class RequestLoggerActionFilter : ActionFilterAttribute
{
    private readonly ILogger _logger;

    public RequestLoggerActionFilter(ILoggerFactory loggerFactory)
    {
        _logger = loggerFactory.CreateLogger("RequestLogger");
    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        var request = context.HttpContext.Request;
        request.Body.Position = 0;

        using (var reader = new StreamReader(request.Body))
        {
            var bodyString = reader.ReadToEnd();
            _logger.LogInformation($"API call recevied on {request.Method.ToUpper()} {request.Path} RequestBody: {bodyString}");
        }

        base.OnActionExecuting(context);
    }
}

Этот фрагмент кода работает нормально в большинстве случаев. У меня проблема, когда мой метод контроллера возвращает код 201, используя метод CreatedAtAction

return CreatedAtAction("Get", new { Id= myObject.Id });

проблема в том, что когда я нажимаю на метод моего контроллера, который создает объект, он впервые входит в мой actionfilter и правильно регистрирует запрос. Затем, когда достигается обратная строка, он попадает в мой фильтр действий второй раз (я не уверен, почему второй запрос отправляется, я думаю, что он делает то же самое, что и перенаправление). Второй раз OnActionExecuting моего actionFilter выполняется, эта строка кода вызывает исключение

request.Body.Position = 0;

'Невозможно получить доступ к удаленному объекту.'

Тело моего запроса удалено. Мой ActionFilter зарегистрирован таким образом в Startup.cs файле

services.AddMvc(c =>
                {
                    c.Filters.Add(typeof(RequestLoggerActionFilter));
                }
            );

Жизненный цикл моего actionFilter - Scoped, я также пробовал Transient, но это не решает проблему.

services.AddScoped<RequestLoggerActionFilter>();

1 Ответ

0 голосов
/ 13 сентября 2018

Я сделал тест с request.EnableRewind(); и кодом ниже, он работает с CreatedAtAction.

    public class RequestLoggerActionFilter : ActionFilterAttribute
{
    private readonly ILogger _logger;

    public RequestLoggerActionFilter(ILoggerFactory loggerFactory)
    {
        _logger = loggerFactory.CreateLogger("RequestLogger");
    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        var request = context.HttpContext.Request;
        request.EnableRewind();
        request.Body.Position = 0;

        using (var reader = new StreamReader(request.Body))
        {
            var bodyString = reader.ReadToEnd();
            _logger.LogInformation($"API call recevied on {request.Method.ToUpper()} {request.Path} RequestBody: {bodyString}");
        }

        base.OnActionExecuting(context);
    }
}
...