12

I'm using MVC Mini profiler to check the speed of specific parts of my application, and would like to keep it there just in case something happens later and I may need to check "what's going wrong". It's not a full log set, but it comes pretty in handy to know what's making a page take long.

So, my goal is to hide it and have it profile only when the request comes with a specific parameter. However, none of my attempts have worked in the way that I would expect.

This has done the trick of not showing it on the screen (code in a view):

@if (Request.QueryString.AllKeys.Contains("showProfiler"))
{ 
    @MvcMiniProfiler.MiniProfiler.RenderIncludes()
}

This is the attempt that got closer. Correctly hides the mini profiler info, but at the moment I show it, it profiles everything since I stopped showing it. So, let's say that I profile my page and it takes 3 seconds. I remove the query parameter and load the page three more times. I add my parameter again and I see 4 sets of profile information. That implies that it keeps track of everything and I wonder it if could give memory issues.

Attempts to make that not happen anymore:

Attempt 1:

protected void Application_BeginRequest()
{
    if (Request.QueryString.AllKeys.Contains("showProfiler"))
    {
        MiniProfiler.Start();
    }
}

Attempt 2:

protected void Application_EndRequest()
{
    MiniProfiler.Stop(!Request.QueryString.AllKeys.Contains("showProfiler"));
}

Attempt 3:

protected void Application_EndRequest()
{
    MiniProfiler.Stop(true);
}

None of these worked. Any ideas?

Alpha
  • 7,586
  • 8
  • 59
  • 92

3 Answers3

13

The home page (see the "Abandoning a Profiler Session section) of the profiler has the usage pattern are looking for:

protected void Application_BeginRequest()
{
   MvcMiniProfiler.MiniProfiler.Start();  
}
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
   if(!CurrentUserIsAllowedToSeeProfiler())
   {
       MvcMiniProfiler.MiniProfiler.Stop(discardResults: true);
   }
}

Your implementation of CurrentUserIsAllowedToSeeProfiler will be checking if the query string contains the key the trigger the profiler.


EDIT:

You can also look at their Example Project to see how they implement disabling it in certain situation. Their check is to see if you are accessing it via localhost, but you could of course change that to check the query string instead.

Based on that, it appears that "Attempt #1" should be the trick. Do note that the difference between the one "that is close" and "attempt #1" is the former is looking for query string profiling, whereas your Attempt #1 is checking for showProfiler. Could it have just been a simple query string mixup?

vcsjones
  • 138,677
  • 31
  • 291
  • 286
  • Thanks! In fact the spelling mistake on the parameter was my issue when creating the post, but the strings are the same in the project. Your answer pointed me to the settings (which I hadn't checked before) and that sample project... I'll try some of it and get back to you. – Alpha Sep 30 '11 at 00:29
  • The Settings didn't have anything to do, exactly as you said, the pattern to use was the one you presented. However, there's no really need to implement `Application_AuthenticateRequest`. I used part of the very same `Application_BeginRequest` method, starting miniprofiler and stopping (and discarding results) if I didn't want to profile a session. Thanks! – Alpha Sep 30 '11 at 00:47
  • @Alpha I agree, there is no reason to use AuthenticateRequest over begin request - I just copied it verbatim from the source since I citing it as a reference. – vcsjones Sep 30 '11 at 00:49
0

I did't find a solution in above.

For me the only solution was to set the debug="false" in the Web.Config file.

<compilation defaultLanguage="c#" debug="false" batch="false" targetFramework="4.5.2">

Hope this helps for other as well.

JanBorup
  • 5,337
  • 1
  • 29
  • 17
0

Just start the profiler like normal in your begin request event. Then in your controller or view, check for the query string and call MiniProfiler.Stop(true) to discard the profiled data if it doesn't or is set to false.

protected void Application_BeginRequest()
{
    MiniProfiler.Start();  
}

Then in your view:

@if(!Request.QueryString.AllKeys.Contains("profiling"))
{
    MiniProfiler.Stop(true);
}
Kyle Trauberman
  • 25,414
  • 13
  • 85
  • 121
  • This could get pretty ugly if you put that code in every action of every controller that you have. In this case, maybe a general approach via a global ActionFilter or via Global.asax would be preferable? – Maxim Zaslavsky Sep 29 '11 at 23:59
  • If you want to avoid repeating the check, you could put it in the `BeginRequest` event, or override `OnActionExecuting` in your controller. – Kyle Trauberman Sep 30 '11 at 00:03
  • Besides the obvious... how different would be calling MiniProfiler.Stop() on the view and not the `Application_EndRequest` method? If none, I didn't get the difference between what I tried and what you suggest, sorry. – Alpha Sep 30 '11 at 00:31
  • You could do it anywhere, really. I mentioned the view, because that's what you mentioned in the question. Its better to stop earlier in the lifecycle to prevent any extra overhead, so BeginRequest would be good. – Kyle Trauberman Sep 30 '11 at 06:13