2017-02-15 82 views
0

我有這個非常簡單的前面一段代碼。Asp.Net服務器端輸出緩存得到了每一個請求(HttpHandler)

有幾件事我嘗試過,我不明白爲什麼服務器端輸出緩存不在http://localhost工作。以下是「緩存設置」的最後一次嘗試,以便而不是在調試輸出窗格上看到HIT。

這讓我瘋狂!我如何防止HIT ...?!當我打開開發工具並檢查禁用緩存時,我期待緩存的服務器端副本,並且在調試輸出窗格中看不到HIT。

我在Windows 8上,但即使在另一個Windows版本(/ IIS版本)上,我也無法想象最終的代碼會有所不同。

using System; 
using System.Diagnostics; 
using System.Net.Http; 
using System.Web; 

namespace WebApplication1 
{ 
    /// <summary> 
    /// Summary description for MyHandler 
    /// </summary> 
    public class MyHandler : IHttpHandler 
    { 
     public void ProcessRequest(HttpContext context) 
     { 
      Debug.WriteLine("HIT"+DateTime.Now.ToLongTimeString()); 

      context.Response.Cache.SetExpires(DateTime.Now.AddMinutes(5)); 
      context.Response.Cache.SetCacheability(HttpCacheability.Server); 
      context.Response.Cache.SetValidUntilExpires(true); 
      context.Response.Cache.SetOmitVaryStar(true); 
      context.Response.Cache.VaryByParams["none"] = true; 
      context.Response.Cache.SetMaxAge(new TimeSpan(0, 5, 0)); 

      // Just here for testing purposes 
      const string url = "http://otherserver/image.png"; 
      using (var client = new HttpClient()) 
      { 
       var task = client.GetStreamAsync(url); 
       task.Wait(); 
       task.Result.CopyTo(context.Response.OutputStream); 
       context.ApplicationInstance.CompleteRequest(); 
      } 
     } 

     public bool IsReusable 
     { 
      get { return true; } 
     } 
    } 
} 

回答

0

事實證明,ApplicationInstance.CompleteRequest()是在我的情況造成的痛苦。根據MSDN它:

導致ASP.NET繞過HTTP管道執行過程中的所有事件和篩選,並直接執行EndRequest事件。

這是被在中間的某個地方執行Asp.Net pipeline flow

Asp.Net pipeline flow

的處理程序,你可以看到,並呼籲ApplicationInstance.CompleteRequest()後,它會跳過一切,並直接發送請求(或CompleteRequest()內部) 。

發生這種情況時,它也會跳過「更新緩存」事件。這是請求緩存被更新的地方;服務器端輸出緩存項目將被添加...

因此,請注意當您認爲您完成HttpHandler時,ApplicationInstance.CompleteRequest()會執行什麼操作!

另一個有趣的閱讀:https://weblog.west-wind.com/posts/2009/May/21/Dont-use-ResponseEnd-with-OutputCache

快樂緩存!