我正在尝试在我的web api站点上设置MiniProfiler,并且很难让MiniProfiler.Current工作.
我按照miniprofiler.com上的说明进行操作,并在global.asax中有以下内容:
protected void Application_Start()
{
MiniProfilerEF6.Initialize();
// other setup
}
protected void Application_BeginRequest() {
// need to start one here in order to render out the UI
MiniProfiler.Start();
}
protected void Application_EndRequest() {
MiniProfiler.Stop();
}
这使用默认的WebRequestProfilerProvider,它将实际的配置文件对象存储在HttpContext.Current.Items中.
当我要求MiniProfiler.Current时,它会查看HttpContext.Current.
当我向我的一个web api网址发出请求时:
> Application_BeginRequest创建探查器,将其存储在HttpContext.Current中
>在web api MessageHandler中,我可以看到HttpContext.Current
>在web apu IActionFilter中,HttpContext.Current现在为null,我对MiniProfiler.Current.Step(“controller:action”)的尝试失败
>我的各种服务运行的EF查询都没有记录,因为miniprofiler hook依赖于MiniProfiler.Current,它依赖于HttpContext.Current,现在为null
> Application_EndRequest触发,HttpContext.Current神奇地回来了,所以它包装了探查器并告诉我自请求开始以来已经有多长时间了
我挖掘了代码,我可以创建自己的IProfileProvider,将探查器对象存储在比HttpContext.Current更可靠的地方,但我不知道它可能在哪里.
我花了几个小时尝试,但找不到可行的解决方案.问题:
> IProfileProvider是一个全局变量; MVC或Web API管道中的所有工作线程都必须使用相同的IProfileProvider
>我可以在web api RequestContext.Properties中挖掘出该请求的HttpContext,但这并没有多大帮助,因为我的IProfileProvider在整个应用程序中是全局的;如果我告诉它将配置文件存储在HttpContext A中,那么对其他HttpContexts的任何同时请求都会污染配置文件
>我不能依赖任何类型的threadstorage,因为async / await动态地重用线程
>我无法将探查器对象与InRequestScope绑定在Ninject绑定中,因为InRequestScope似乎不适用于web api 2.1,但即使我可以
>每个人都说HttpRequestMessage.Properties是新的HttpContext.Current.Items,但同样,IProfileProvider是一个全局变量,我不知道如何确保每个请求都在查看他们的版本HttpRequestMessage. MiniProfiler.Current可以从任何地方调用,所以我想全局IProfileProvider必须以某种方式检查调用堆栈并在那里找到HttpRequestMessage?这听起来像疯了似的.
我不知所措.我真正想要的是special variable.
最佳答案 把问题放在一起的过程我弄明白了.异步/等待事物时,HttpContext.Current可能会丢失:
Why is HttpContext.Current null after await?
我必须在那里列出web.config更改,并在等待之前调整我的过滤器以使用Miniprofiler.Current.