I'm trying to setup MiniProfiler on my web api site, and having a hard time getting MiniProfiler.Current
to work.
I followed the directions at miniprofiler.com, and have the following in 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();
}
This uses the default WebRequestProfilerProvider, which stores the actual profile object in HttpContext.Current.Items
.
When I ask for MiniProfiler.Current
, it looks to HttpContext.Current
.
When I make a request for one of my web api URLs:
Application_BeginRequest
creates the profiler, store it in HttpContext.Current
MessageHandler
, I can see HttpContext.Current
IActionFilter
, HttpContext.Current
is now null, and my attempt to MiniProfiler.Current.Step("controller:action")
failsMiniProfiler.Current
, which relies on HttpContext.Current
, which is null right nowApplication_EndRequest
fires, and HttpContext.Current
is magically back, and so it wraps up the profiler and tells me how long it's been since the request beganI dug through the code, and I can create my own IProfileProvider
, to store the profiler object somewhere more reliable than HttpContext.Current
, but I don't know where that could be.
I spent a few hours trying things out, but couldn't find a workable solution. The problems:
IProfileProvider
is a global variable; all worker threads in either the MVC or Web API pipeline all have to use the same IProfileProvider
IProfileProvider
is global across the entire app; If I tell it to store the profile in HttpContext A, then any simultaneous requests for other HttpContexts are going to pollute the profileInRequestScope
because InRequestScope
doesn't seem to work with web api 2.1, but even if I couldHttpRequestMessage.Properties
is the new HttpContext.Current.Items
, but again, IProfileProvider
is a global variable and I don't know of a way to ensure each request is looking at their version HttpRequestMessage
. MiniProfiler.Current
can be called from anywhere, so I guess a global IProfileProvider
would have to somehow inspect the call stack to and find an HttpRequestMessage
there? That sounds like madness.I'm at a loss. What I really want is a special variable.
The process of putting the question together I figured it out. HttpContext.Current
can get lost when you async/await things: Why is HttpContext.Current null after await?
I had to make the web.config change listed there, and adjusted my filters to use Miniprofiler.Current
before any await
ing.
Also discussed at https://www.trycatchfail.com/2014/04/25/using-httpcontext-safely-after-async-in-asp-net-mvc-applications/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With