Asp.Net核心ActionFilter上下文请求正文处理完毕

问题描述 投票:0回答:1

我有一个asp.net核心web api项目,我在其中创建了一个动作过滤器来记录对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);
    }
}

在大多数情况下,这段代码可以正常工作。当我的控制器方法使用CreatedAtAction方法返回201代码时,我遇到了问题

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

问题是,当我点击创建对象的控制器方法时,它会在我的actionfilter中第一次进入并正确记录请求。然后,当到达返回行时,它再次击中我的actionfilter(我不确定为什么发送第二个请求,我猜它有点像重定向一样)。第二次执行actionFilter的OnActionExecuting时,这行代码会引发异常

request.Body.Position = 0;

“无法访问已处置的对象。”

处理我的请求的正文。我的ActionFilter在Startup.cs文件中以这种方式注册

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

我的actionFilter的生命周期是Scoped,我也试过Transient,但它没有解决问题。

services.AddScoped<RequestLoggerActionFilter>();
asp.net-core dependency-injection asp.net-core-webapi
1个回答
0
投票

我用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);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.