ASP.NET MVC - 您可以检测静态资源请求的请求周期中最早的一点是什么?

时间:2011-07-26 00:11:10

标签: c# asp.net-mvc asp.net-mvc-3 profiling static-resource

为了给问题提供一些上下文,我编写了一个在Application_BeginRequest上调用的探查器,但它记录了所有内容(即javascripts,图像等)。虽然作为最后的手段可以向探查器客户端添加过滤,但我更倾向于仅在可以确定请求需要路由时激活探查器。理想情况下,它将在Application_BeginRequest中,但我不认为没有冗余处理传入的路由请求...

简而言之,请求生命周期中最早的一点是什么时候我可以确定请求是否属于静态资源,你会怎么做呢?

是否可以从System.Web.Routing.RouteTable派生或挂钩并从那里调用我的探查器代码?

3 个答案:

答案 0 :(得分:2)

有各种选择。 首先 - 使用Request.PhysicalPath确定静态文件 - 检查: Check for a static file during Application_BeginRequest?

另一种方法是将其作为处理程序,并使用路径来记录要包含的文件类型(* .aspx),例如在web.config中。然后你可以很早就访问事件(参见asp.net管道)

或者只使用httpmodule - 检查所有内容,并仅在您提及的情况下分析非物理项目。

或者 - 使用您当前的方法与第一个链接,只需检查Request.PhysicalPath并希望它适合您:)

答案 1 :(得分:2)

我宁愿使用 MVC过滤器进行性能分析,因为MVC过滤器允许添加预处理和后处理行为, filterContext 参数应该为您提供足够的信息。

例如,我将创建ProfilerAttribute以进行性能分析

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");
    }
}

并在 Global.ascx ....

中注册为GlobalFilter
public static void RegisterGlobalFilters(GlobalFilterCollection filters) {
    filters.Add(new HandleErrorAttribute());
    filters.Add(new ProfilerAttribute());
}

希望它可以提供帮助。谢谢。

更新:忘记提及MVC过滤器仅在路由匹配后才执行。因此,您不需要过滤掉静态资源,因为它已经由MVC完成。

答案 2 :(得分:1)

我尝试从不同的角度接近它,并对结果更加满意。基本上 - 为什么在你根本不能“路由”它们时检测静态资源请求?在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
}

现在我不再需要检查静态请求,但如果我确实想要出于某种原因我仍然可以执行以下操作:

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]);
}

由于我绝对肯定地知道我将提供静态内容的唯一路径是什么,这似乎是一个相当强大的解决方案。我仍然对其他想法持开放态度,但我认为这很符合我的需求。