我有一个asp.net核心网络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的OnActionExecuting
时,此代码行引发异常
request.Body.Position = 0;
“无法访问已处置的对象。”
我的请求正文已被处理。我的ActionFilter以这种方式注册在Startup.cs
文件中
services.AddMvc(c =>
{
c.Filters.Add(typeof(RequestLoggerActionFilter));
}
);
我的actionFilter的生命周期是有作用域的,我也尝试过Transient,但这不能解决问题。
services.AddScoped<RequestLoggerActionFilter>();
答案 0 :(得分: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);
}
}