2011-07-26 20 views
1

爲了給出這個問題的一些上下文,我寫了一個在Application_BeginRequest上調用的分析器,但它記錄了一切(即javascript,圖像等)。儘管可以作爲向探查器客戶端添加過濾器的最後手段,但我更願意僅在確定請求需要路由時才激活探查器。理想情況下,它將在Application_BeginRequest中,但我認爲沒有對傳入請求進行冗餘處理是不可能的...ASP.NET MVC - 請求週期中可以檢測靜態資源請求的最早點是什麼?

因此,簡而言之,請求生命週期中的最早點是什麼時候,我可以確定如果一個請求是一個靜態資源或不是,你會怎麼做呢?

是否有可能從System.Web.Routing.RouteTable派生或掛鉤並從那裏調用我的Profiler代碼?

回答

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

因爲我知道有絕對肯定我將從靜態內容提供的唯一路徑是什麼,這似乎是一個相當強大的解決方案。我仍然接受其他想法,但我認爲這很適合我的需求。

2

有多種選擇。 首先 - 使用Request.PhysicalPath確定靜態文件 - 退房: Check for a static file during Application_BeginRequest?

一種選擇是將有此作爲一個處理程序,並使用路徑需要注意的文件類型包括(*的.aspx)例如在你的web.config。然後你就可以很早地訪問事件(參見asp.net管道)

或者只是使用httpmodule - 檢查所有內容,只檢查你提到的非物理項目。

或 - 使用當前的方法與第一連桿簡單地檢查Request.PhysicalPath,希望對你有用:)

+0

Request.PhysicalPath方法的問題是假設請求是靜態的,如果請求可以直接映射到文件名,並且如果不是靜態請求則不是。例如,我不希望僅僅因爲文件不存在於磁盤上而將錯誤鏈接或對已刪除映像文件的引用解釋爲非靜態鏈接。 – nathanchere

+0

然後,您的代碼可能需要檢查響應代碼以確定此情況(儘管同樣可以應用缺少的動態文件),因爲根據定義,以上是物理文件是靜態的,而您正在尋找靜態文件類型。要真正檢測到您需要進行文件類型假設或查詢iis或配置所有映射的應用程序。從技術上講,我可以通過將.js映射到aspnet_isapi或另一個httphandler來使動態文件成爲動態文件,因此您想在哪裏繪製線? –

2

我寧願使用分析MVC過濾器因爲MVC過濾器允許添加預處理和後處理的行爲和filterContext參數應該給你足夠的信息。

例如,我會爲剖析

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

創建ProfilerAttribute並註冊爲GlobalFilterGlobal.ascx ....

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

希望它可以幫助。謝謝。

更新:忘了提的是,MVC篩選器僅執行路由後匹配。所以,你不需要過濾掉靜態資源,因爲它已經由MVC完成了。

+0

我最初在派生控制器類的ActionExecuting和actionExecuted上使用調用,但問題在於它忽略了像View View,Routing等這些我想要能夠配置的事情。 – nathanchere

+1

通過實現IResultFilter,如果您的操作結果爲ViewResult,則可以像配置View一樣進行配置文件配置。因此,您將知道控制器操作是否緩慢或執行結果是否緩慢。由於路由是Asp.net的一部分,因此您無法在性能上做太多工作。爲了分析ASP.NET運行時,您可以使用ASP.NET的性能計數器。 http://goo.gl/uRB8f :) –

+0

此MSDN雜誌文章也許對您有用.. http://msdn.microsoft.com/en-us/magazine/hh288078.aspx –