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

C# ASP.NET MVC-在请求周期中最早可以检测到静态资源请求的点是什么?,c#,asp.net-mvc,asp.net-mvc-3,profiling,static-resource,C#,Asp.net Mvc,Asp.net Mvc 3,Profiling,Static Resource,为了给这个问题提供一些上下文,我编写了一个profiler,它在应用程序_BeginRequest上调用,但它记录了所有内容,如javascripts、图像等。作为最后的手段,可以向profiler客户端添加过滤,我宁愿只在可以确定请求需要路由时激活探查器。理想情况下,它会出现在应用程序_BeginRequest中,但我认为如果不对传入的路由请求进行冗余处理,这是不可能的 简言之,在请求生命周期中,我可以确定一个请求是否用于静态资源的最早时间点是什么时候,您将如何进行 是否可能从System.W

为了给这个问题提供一些上下文,我编写了一个profiler,它在应用程序_BeginRequest上调用,但它记录了所有内容,如javascripts、图像等。作为最后的手段,可以向profiler客户端添加过滤,我宁愿只在可以确定请求需要路由时激活探查器。理想情况下,它会出现在应用程序_BeginRequest中,但我认为如果不对传入的路由请求进行冗余处理,这是不可能的

简言之,在请求生命周期中,我可以确定一个请求是否用于静态资源的最早时间点是什么时候,您将如何进行

是否可能从System.Web.Routing.RouteTable派生或挂接到System.Web.RouteTable并从中调用我的探查器代码?

有多种选项。 首先-要使用Request.PhysicalPath确定静态文件-签出:

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

或者只使用一个httpmodule-检查所有内容,只分析您提到的非物理项

或者-在第一个链接中使用您当前的方法,只需检查Request.PhysicalPath,并希望它对您有效:

有各种选项。 首先-要使用Request.PhysicalPath确定静态文件-签出:

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

或者只使用一个httpmodule-检查所有内容,只分析您提到的非物理项


或者-在第一个链接中使用您当前的方法,只需检查Request.PhysicalPath并希望它对您有效:

我尝试从不同的角度处理它,并且对结果感到非常高兴。基本上-当您根本无法“路由”静态资源请求时,为什么要检测它们?在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]);
}

因为我绝对肯定地知道我将从哪些路径提供静态内容,所以这似乎是一个相当健壮的解决方案。我仍然对其他想法持开放态度,但我认为这很适合我的需要。

我试着从不同的角度来看待它,并且对结果感到非常高兴。基本上-当您根本无法“路由”静态资源请求时,为什么要检测它们?在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]);
}
因为我绝对肯定地知道我将从哪些路径提供静态内容,所以这似乎是一个相当健壮的解决方案。我仍然对其他想法持开放态度,但我认为这很适合我的需要。

我宁愿使用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

希望能有所帮助。谢谢

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

我宁愿使用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

希望能有所帮助。谢谢


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

我最初使用对派生控制器类的ActionExecuting和actionExecuted的调用,但问题是它遗漏了视图渲染、路由等我希望能够分析的内容。通过实现IResultFilter,如果操作结果是ViewResult,则可以使用类似于视图渲染的配置文件。所以,您将知道控制器的动作是慢还是执行结果慢。因为路由是Asp.net的一部分,所以在性能方面你不能做太多。要分析ASP.NET运行时,可以使用ASP.NET的性能计数器:这篇MSDN杂志文章也可能对你有用。。我最初使用对派生控制器类的ActionExecuting和actionExecuted的调用,但问题是它忽略了视图渲染、路由等我希望能够分析的内容
使用IResultFilter,如果操作结果是ViewResult,则可以使用类似于视图渲染的配置文件。所以,您将知道控制器的动作是慢还是执行结果慢。因为路由是Asp.net的一部分,所以在性能方面你不能做太多。要分析ASP.NET运行时,可以使用ASP.NET的性能计数器:这篇MSDN杂志文章也可能对你有用。。Request.PhysicalPath方法的问题在于,如果请求可以直接映射到文件名,则该方法假定该请求是静态的,如果请求不能直接映射到文件名,则该请求不是静态的。例如,我不想,错误命名的链接或对已删除图像文件的引用将被解释为非静态链接,只是因为该文件在磁盘上不存在。然后,您的代码可能需要检查响应代码以确定这种情况,但同样的情况也可能适用于缺少的动态文件,因为根据定义,上面的物理文件是静态的,而您是静态的正在查找静态文件类型。要真正检测到您需要对文件类型进行假设,或者查询iis或应用程序配置中的所有映射。从技术上讲,只要将.js映射到aspnet_isapi或另一个httphandler,我就可以让它成为一个动态文件。那么,您想在哪里划清界限呢?Request.PhysicalPath方法的问题是,如果请求可以直接映射到文件名,那么它假定请求是静态的,如果请求不能直接映射到文件名,那么它就不是静态的请求。例如,我不想,错误命名的链接或对已删除图像文件的引用将被解释为非静态链接,只是因为该文件在磁盘上不存在。然后,您的代码可能需要检查响应代码以确定这种情况,但同样的情况也可能适用于缺少的动态文件,因为根据定义,上面的物理文件是静态的,而您是静态的正在查找静态文件类型。要真正检测到您需要对文件类型进行假设,或者查询iis或应用程序配置中的所有映射。从技术上讲,只要将.js映射到aspnet_isapi或另一个httphandler,我就可以让它成为一个动态文件,那么您想在哪里划清界限呢?