我创建了一个动作过滤器,用于测量Web API v2中每个动作的运行时间。
public class RunningTimeAttribute : ActionFilterAttribute
{
private readonly ILogFactory _logFactory;
private readonly ITimerFactory _timerFactory;
private ITimer _timer;
private ILogger _logger;
public RunningTimeAttribute(ILogFactory logFactory, ITimerFactory timerFactory) {
if(logFactory == null)
throw new ArgumentNullException("logFactory");
if(timerFactory == null)
throw new ArgumentNullException("timerFactory");
_logFactory = logFactory;
_timerFactory = timerFactory;
}
public override void OnActionExecuting(HttpActionContext actionContext) {
base.OnActionExecuting(actionContext);
OnBeforeAction(actionContext);
}
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) {
OnAfterAction(actionExecutedContext);
base.OnActionExecuted(actionExecutedContext);
}
private void OnBeforeAction(HttpActionContext actionContext) {
var controllerName = actionContext.ControllerContext.Controller.GetType().FullName;
var actionName = actionContext.ActionDescriptor.ActionName;
_logger = _logFactory.Create(controllerName);
_logger.Trace("Action \"{0}\" begins execution", actionName);
_timer = _timerFactory.Create();
_timer.Start();
}
private void OnAfterAction(HttpActionExecutedContext actionExecutedContext) {
var actionName = actionExecutedContext.ActionContext.ActionDescriptor.ActionName;
_timer.Stop();
_logger.Trace("Time elapsed for action \"{0}\": {1} msec", actionName, _timer.ElapsedMilliseconds);
}
}
但是,操作过滤器充当单例,因此当OnActionExecuted
运行时,我无法确定_logger
和_timer
是否与为相同的操作创建的OnActionExecuting
{ {1}}
EG。
_logger = "logger1"
,_timer = "timer1"
。_logger = "logger2"
,_timer = "timer2"
(他们被覆盖) 问题:我可以在OnActionExecuted
中了解OnActionExecuting
对应的方式吗?如果有一些唯一的动作标识符,我可以将它用作Dictionary的一个键来存储任何与动作相关的对象,如记录器和定时器。有没有?还是其他一些解决方案?
答案 0 :(得分:6)
就Web API而言,System.Web.HttpContext.Current
并不总能得到保证。这取决于您是否使用Web API Self托管。这就是当覆盖System.Web.Http.Filters.ActionFilterAttribute.OnActionExecuting
时你没有在HttpActionContext
参数上获得httpcontext属性的主要原因(在AspNet MVC中)。
执行相同操作的最佳方式是actionContext.Request.Properties
字典。
同时查看此答案here
答案 1 :(得分:1)
System.Web.HttpContext.Current.Items是每请求缓存存储 您可以安全地在OnBeforeAction方法的Items中添加计时器对象,并从OnAfterAction方法中的Items中检索此计时器对象