Question

To give the question some context, I've written a profiler which is called on Application_BeginRequest but it's logging everything (ie javascripts, images etc). While it would be possible as a last resort to add filtering to the profiler client, I'd much rather only activate the profiler when it can be determined that the request requires routing. Ideally it would be in Application_BeginRequest but I don't think it would be possible without redundant processing of the incoming request for routing...

So in short, when is the earliest point in the request life cycle that I can determine if a request is for a static resource or not, and how would you go about it?

Is it perhaps possible to derive from or hook into System.Web.Routing.RouteTable and call my profiler code from there?

Was it helpful?

Solution 3

I've tried approaching it from a different angle and am much happier with the result. Basically - why detect static resource requests when you can just not 'route' them at all? In global.asax:

private readonly string[] STATIC_CONTENT_PATHS = new string[] { "css", "js", "img" }; 

public static void RegisterRoutes(RouteCollection routes)
{    
    foreach (string path in STATIC_CONTENT_PATHS) { routes.IgnoreRoute(path + @"/{*foo}"); }

    // other MapRoute calls here
}

Now I no longer need to check for static requests, although if I do want to for whatever reason I can still do the following:

protected void Application_BeginRequest()
{            
    if (IsStaticRequest())
    {
         // do something here
    }
}

private bool IsStaticRequest()
{
   var result = Request.Url.AbsolutePath.Split('/');
   if (result.Length < 2) return false;
   return STATIC_CONTENT_PATHS.Contains(result[1]);
}

Since I know with absolute certainly what the only paths I'll be serving static content from are, this seems like a fairly robust solution. I'm still open to other ideas but I think this suits my needs well.

OTHER TIPS

There are various options. First - to determine the static file using Request.PhysicalPath - check out: Check for a static file during Application_BeginRequest?

One alternative would be to have this as a handler and use the path to note the file types to include (*.aspx) for example in your web.config. Then you can have access to events pretty early on (see asp.net pipeline)

Or just use an httpmodule - check everything and only profile the non-physical items as you mention.

Or - use your current method with the first link to simply check Request.PhysicalPath and hope that works for you : )

I would rather use MVC Filters for profiling since MVC Filters allow to add pre- and post-processing behaviours and filterContext parameter should give you enough information.

For example, I would create ProfilerAttribute for profiling

public class ProfilerAttribute : FilterAttribute, IActionFilter, IResultFilter, IExceptionFilter {
    public void OnActionExecuting(ActionExecutingContext filterContext) {
        Debug.WriteLine("Before Action is executing");
    }

    public void OnActionExecuted(ActionExecutedContext filterContext) {
        Debug.WriteLine("After Action is executed");
    }

    public void OnResultExecuted(ResultExecutedContext filterContext) {
        Debug.WriteLine("After Action Result is executed");            
    }

    public void OnResultExecuting(ResultExecutingContext filterContext) {
        Debug.WriteLine("Before Action Result is executing");
    }

    public void OnException(ExceptionContext filterContext) {
        Debug.WriteLine("oops! exception");
    }
}

and register as GlobalFilter in Global.ascx....

public static void RegisterGlobalFilters(GlobalFilterCollection filters) {
    filters.Add(new HandleErrorAttribute());
    filters.Add(new ProfilerAttribute());
}

Hope it can help. Thanks.

update: Forgot to mention that the MVC Filter only executed after the routing is matched. So, you don't need to filter out for static resources since it was already done by MVC.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top