2008-08-28 24 views
24

在編寫一個自定義的IHttpHandler時,我遇到了一個我沒有想到的有關HttpCachePolicy對象的行爲。爲什麼HttpCacheability.Private壓制ETags?

我的處理程序計算並設置的實體標籤(使用與當前響應對象相關聯的爲HttpCachePolicy的SetETag方法)。如果我使用SetCacheability方法將緩存控件設置爲公共,則所有的工作都像魅力一樣,並且服務器沿着電子標籤頭髮送。如果我將其設置爲私人,電子標籤標題將被取消。

也許我只是還沒有看夠硬,但我還沒有看到在HTTP/1.1規範任何會證明這種行爲。你爲什麼不想將E-Tag發送給瀏覽器,同時還禁止代理存儲數據?

using System; 
using System.Web; 

public class Handler : IHttpHandler { 
    public void ProcessRequest (HttpContext ctx) { 
     ctx.Response.Cache.SetCacheability(HttpCacheability.Private); 
     ctx.Response.Cache.SetETag("\"static\""); 
     ctx.Response.ContentType = "text/plain"; 
     ctx.Response.Write("Hello World"); 
    } 

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

將返回

 
Cache-Control: private 
Content-Type: text/plain; charset=utf-8 
Content-Length: 11 

但是,如果我們將其改爲公開它會返回

 
Cache-Control: public 
Content-Type: text/plain; charset=utf-8 
Content-Length: 11 
Etag: "static" 

我的ASP.NET開發服務器上運行,這和IIS6至今具有相同的結果。另外我無法使用

Response.AppendHeader("ETag", "static") 

更新明確設置的ETag:這是可能的ETag頭手動附加在IIS7運行的時候,我懷疑這是由ASP.NET和之間的緊密集成引起IIS7管道。

澄清:這是一個長期的問題,但核心問題是:爲什麼ASP.NET做到這一點,我怎樣才能繞過它,我應該?

更新:我要接受Tony's answer,因爲它本質上是正確的(去託尼!)。我發現如果你想完全模擬HttpCacheability.Private,你可以設置緩存到ServerAndPrivate,但你也有呼叫緩存。 SetOmitVaryStar(true)否則緩存會將Vary:*標頭添加到輸出中,您不希望發生這種情況。當我獲得編輯權限時(或者如果你看到這個Tony或許你可以編輯你的答案來包含那個調用?),我會將其編輯到答案中(

回答

17

我認爲你需要使用HttpCacheability.ServerAndPrivate

這應該給你的Cache-Control:私人的頭,讓你設置一個ETag。

關於這方面的文檔需要更好一些。

編輯: Markus發現你也有調用cache.SetOmitVaryStar(true),否則緩存將Vary:*頭添加到輸出,你不想這樣做。

+2

我不知道如果[這個答案](http://stackoverflow.com/a/2633452/1869660)到一個不同的問題描述了爲什麼@Markus將調用添加到`SetOmitVaryStar()`,但作爲的ASP.NET 4.0可能不再需要它。 – Sphinxxx 2014-07-22 22:48:41

3

不幸的是,如果你在.NET Reflector中看到System.Web.HttpCachePolicy.UpdateCachedHeaders(),你會看到一個if語句,在執行任何ETag操作之前特別檢查Cacheability是否不公開。無論如何,我總是發現Last-Modified/If-Modified-Since適合我們的數據,並且無論如何都更容易在Fiddler中進行監控。

0

如果像我一樣,您對使用Cacheability.ServerAndPrivate時提到的解決方法感到不滿意,並且您確實想使用Private來代替 - 也許是因爲您是爲用戶單獨定製頁面,並且在服務器上緩存沒有意義 - 那麼至少在.NET 3.5中,你可以通過Response.Headers.Add來設置ETag,這個工作正常。

N.B.如果你這樣做,你必須自己實現客戶端頭和HTTP 304響應處理的比較 - 不確定.NET在正常情況下是否處理這個問題。

+3

您總是可以調用`HttpCachePolicy.SetNoServerCaching`來禁用輸出緩存(即服務器緩存)。這將覆蓋「HttpCacheability.ServerAndPrivate」的「服務器」部分。 – 2014-10-09 13:02:46