2013-07-11 126 views
2

給出的通用處理器:ASP.net緩存ASHX文件服務器端

<%@ WebHandler Language="C#" Class="autocomp" %> 

using System; 
using System.Text; 
using System.Text.RegularExpressions; 
using System.Web; 
using System.Web.UI; 

public class autocomp : IHttpHandler { 

    public void ProcessRequest (HttpContext context) { 

     context.Response.ContentType = "application/json"; 
     context.Response.BufferOutput = true; 

     var searchTerm = (context.Request.QueryString["name_startsWith"] + "").Trim(); 

     context.Response.Write(searchTerm); 
     context.Response.Write(DateTime.Now.ToString("s")); 

     context.Response.Flush(); 
    } 

    public bool IsReusable { 
     get { 
      return false; 
     } 
    } 

} 

我怎麼會server side緩存文件1小時基礎上,name_startsWith查詢字符串參數?隨着網絡用戶控制它很簡單:

<%@ OutputCache Duration="120" VaryByParam="paramName" %> 

但我一直在尋找了一段時間做同樣的與通用處理器(ashx)文件並不能找到任何解決方案。

+0

你會在客戶端上使用[這個東西(緩存http://stackoverflow.com/questions/1109768/how-to-use-output-caching-on -ashx-handler),然後在您要獲取數據時使用HttpContext.Cache將實際數據用於服務器端緩存。但是你不能爲此使用任何類型的輸出緩存。此外,請記住確保您的HttpContext.Cache代碼是線程安全的。 ;) – Tombala

+0

在下面編輯我的答案以回答對帖子的更改。 –

回答

7

使用您提供的代碼,您告訴最終用戶瀏覽器將結果緩存30分鐘,因此您沒有執行任何服務器端緩存。

如果你想緩存結果服務器端,你可能會尋找HttpRuntime.Cache。這將允許您將項目插入全局可用的緩存中。然後在頁面加載時,您需要檢查緩存項目的存在,然後如果該項目不存在或在緩存中過期,請轉至數據庫並檢索對象。

編輯

有了更新的代碼示例中,我發現https://stackoverflow.com/a/6234787/254973這在我的測試工作。所以在你的情況下,你可以這樣做:

public class autocomp : IHttpHandler 
{ 
    public void ProcessRequest(HttpContext context) 
    { 
     OutputCachedPage page = new OutputCachedPage(new OutputCacheParameters 
     { 
      Duration = 120, 
      Location = OutputCacheLocation.Server, 
      VaryByParam = "name_startsWith" 
     }); 

     page.ProcessRequest(HttpContext.Current); 

     context.Response.ContentType = "application/json"; 
     context.Response.BufferOutput = true; 

     var searchTerm = (context.Request.QueryString["name_startsWith"] + "").Trim(); 

     context.Response.Write(searchTerm); 
     context.Response.Write(DateTime.Now.ToString("s")); 
    } 

    public bool IsReusable 
    { 
     get 
     { 
      return false; 
     } 
    } 
    private sealed class OutputCachedPage : Page 
    { 
     private OutputCacheParameters _cacheSettings; 

     public OutputCachedPage(OutputCacheParameters cacheSettings) 
     { 
      // Tracing requires Page IDs to be unique. 
      ID = Guid.NewGuid().ToString(); 
      _cacheSettings = cacheSettings; 
     } 

     protected override void FrameworkInitialize() 
     { 
      base.FrameworkInitialize(); 
      InitOutputCache(_cacheSettings); 
     } 
    } 
} 
+0

'OutputCachedPage'是位於代碼示例底部的自定義密封類。沒有需要的程序集/名稱空間。 –

+0

對不起,傻了我。我將該處理程序複製並粘貼到我的項目中,但輸出不是緩存。它似乎沒有工作。 –

+0

@TomGullen我的道歉,刪除'context.Response.Flush()'ProcessRequest'的結尾,它再次爲我工作。我在http://outputcachetest.azurewebsites.net/CacheTest.ashx?name_startsWith=t vs http://outputcachetest.azurewebsites.net/CacheTest.ashx?name_startsWith= anyvaluehere –

0

IIS不使用Max Age來緩存任何內容,因爲它不是HTTP代理。

這是因爲您沒有設置某個相關文件的上次修改日期時間。 IIS需要緩存依賴性(文件依賴性,以便它可以檢查上次更新時間)並將其與緩存進行比較。 IIS不能用作HTTP代理,因此它不會將項目緩存30秒,而是IIS只會根據某種日期時間或某種緩存變量更新緩存。

您可以添加緩存依賴關係,稱爲「文件依賴關係」和「Sql緩存依賴關係」。

動態緩存如何在IIS中工作,可以說你有一個html文件。 IIS將靜態HTML文本視爲可緩存文件,並將其緩存並將緩存副本放入其緩存中。如果靜態html的上次更新時間比緩存時間早,那麼它將使用緩存。如果文件被修改,IIS會發現html的最後更新時間大於緩存時間,所以它會重置緩存。

對於動態內容,您必須相應地規劃您的緩存。如果您基於存儲在SQL表中某行的內容提供內容,那麼您應該跟蹤該行上的最後一次更新時間,並在IIS上添加對IIS的緩存依賴性以查詢您嘗試緩存的項目的上次更新時間。

0

對於多個查詢字符串參數

public class test : IHttpHandler 
{ 

    public void ProcessRequest(HttpContext context) 
    { 
     OutputCachedPage page = new OutputCachedPage(new OutputCacheParameters 
     { 
      Duration = 120, 
      Location = OutputCacheLocation.Server, 
      VaryByParam = "name;city" 
     }); 

     page.ProcessRequest(HttpContext.Current); 

     context.Response.ContentType = "application/json"; 
     context.Response.BufferOutput = true; 

     var searchTerm = (context.Request.QueryString["name"] + "").Trim(); 
     var searchTerm2 = (context.Request.QueryString["city"] + "").Trim(); 

     context.Response.Write(searchTerm+" "+searchTerm2+" "); 
     context.Response.Write(DateTime.Now.ToString("s")); 
    } 

    public bool IsReusable 
    { 
     get 
     { 
      return false; 
     } 
    } 
    private sealed class OutputCachedPage : Page 
    { 
     private OutputCacheParameters _cacheSettings; 

     public OutputCachedPage(OutputCacheParameters cacheSettings) 
     { 
      // Tracing requires Page IDs to be unique. 
      ID = Guid.NewGuid().ToString(); 
      _cacheSettings = cacheSettings; 
     } 

     protected override void FrameworkInitialize() 
     { 
      base.FrameworkInitialize(); 
      InitOutputCache(_cacheSettings); 
     } 
    } 
}