12

I am trying to use the MvcMiniProfiler in my Asp.Net MVC application. I installed the latest NuGet package and added all the code from the wiki page into Application_BeginRequest(), Application_AuthenticateRequest() and in my view.

Upon loading the page, all of the mini profiler's javascript files are being included and correctly downloaded from the server, but when it attempts to get the results Chrome shows:

GET http://localhost:59269/mini-profiler-results?id=59924d7f-98ba-40fe-9c4a-6a163f7c9b08&popup=1 404 (Not Found)

I assume this is due to no routes being setup with MVC to allow for the /mini-profiler-results however I cannot find a way to do that. Looking at the Google code page, their Global.asax.cs file of their sample app has gone through several changes, with one time using MvcMiniProfiler.MiniProfiler.RegisterRoutes(), a second using MvcMiniProfiler.MiniProfiler.Init(), and a third style which does nothing of the sort. The previously mentioned two functions do not exist, so I assume they have been phased out.

At this point I'm unsure of how I can fix this error and use the profiler in my app. Any ideas?


My Global.Asax.cs file looks like:

public class Global : System.Web.HttpApplication
{
    protected void Application_BeginRequest()
    {
        MvcMiniProfiler.MiniProfiler.Start();
    }

    protected void Application_AuthenticateRequest(Object sender, EventArgs e)
    {
        // Only show profiling to admins
        if (!Roles.IsUserInRole(Constants.AdminRole))
            MvcMiniProfiler.MiniProfiler.Stop(discardResults: true);
    }

    protected void Application_Start(object sender, EventArgs e)
    {
        AreaRegistration.RegisterAllAreas();
        RegisterRoutes(RouteTable.Routes);
    }

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.IgnoreRoute("{resource}.aspx/{*pathInfo}");

        routes.MapRoute(
        "Default",
            // Route name
        "{controller}/{action}/{id}",
            // URL with parameters
        new { controller = "Home", action = "Index", id = "" }
            // Parameter defaults
        );
    }
}
KallDrexx
  • 27,229
  • 33
  • 143
  • 254
  • 2
    It looks like this all happens off the static constructor now... looking... – Marc Gravell Jun 27 '11 at 18:48
  • btw, to avoid overhead you should avoid calling Start *all* the time; we do it based on a cookie, which we then verify later in the pipeline (when the user is available). – Marc Gravell Jun 27 '11 at 19:11
  • 2
    Oh, the wiki page made me think that the way I did it above is the usual/accepted way to do it. Should I instead call "Start" in the Application_AuthenticateRequest() method? – KallDrexx Jun 27 '11 at 19:14
  • 1
    Hmmm.... status-reproduced ;p Looking – Marc Gravell Jun 27 '11 at 19:15
  • Wahoo, glad it's not me doing something crazy wrong :) – KallDrexx Jun 27 '11 at 19:16
  • @KallDrexx, you're not off the hook yet. :) – bzlm Jun 27 '11 at 19:20
  • by update do you mean update to your SO answer, cause I don't see an update (unless I'm going blind)? – KallDrexx Jun 27 '11 at 19:29
  • oh, and don't call *stop* during authentication if the user is allowed the data; it is fine to call stop if they **aren't** allowed, but don't call Stop if they are – Marc Gravell Jun 27 '11 at 19:33
  • I meant should I be calling Start() during authentication, since you say I shouldn't be calling start in BeginRequest (even though the google code wiki says otherwise) – KallDrexx Jun 27 '11 at 19:33
  • @KallDrexx calling Start is fine; it is calling *stop* that kills things. Actually, I'd use begin-request for Start, and double-check later – Marc Gravell Jun 27 '11 at 19:41

1 Answers1

22

The RegisterRoutes() method is now called automatically (and with appropriate write-locks, etc) by the static constructor, which should in turn be called when you first call MiniProfiler.Start(). This should inject the routes into the route-table.

So unless you are explicitly clearing the route-table at some point after you have first touched the profiler, it should (all things being equal) work.

I wonder if this is a security thing. For example, which version of IIS are you running with? In some configs (IIS6 in particular) the path needs to be recognised by the server, or you need to enable a wildcard. If this is the case, please let me know - maybe we can implement some kind of fallback route to an ashx or something.


Update: the problem is that you aren't saving the results at the end of the query; there is both short-term and long-term storage, and both have default implementations provided - all you need to do is something like:

protected void Application_EndRequest(object sender, EventArgs e)
{
    MiniProfiler.Stop(discardResults: !IsAnAdmin());
}

Update update: you may also need to add the following to web.config, in the <system.webServer>, <handlers> section:

<add name="MiniProfiler" path="mini-profiler-resources/*" verb="*"
    type="System.Web.Routing.UrlRoutingModule" resourceType="Unspecified"
    preCondition="integratedMode" />
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Adding the entry in web.config got MiniProfiler generally working for me once deployed. Wasn't needed at all for local dev. Still getting some 404s for /mini-profiler-resources/results though – DaveD Sep 19 '14 at 14:10