質問

カスタム IHttpHandler を作成しているときに、HttpCachePolicy オブジェクトに関して予期しない動作に遭遇しました。

私のハンドラーは、エンティティ タグを計算して設定します (現在の応答オブジェクトに関連付けられた HttpCachePolicy の SetETag メソッドを使用します)。SetCacheability メソッドを使用してキャッシュ コントロールを public に設定すると、すべてが魔法のように機能し、サーバーは e-tag ヘッダーに沿って送信します。プライベートに設定すると、e-tag ヘッダーが抑制されます。

私が十分に調べていないだけかもしれませんが、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でこれを実行しましたが、同じ結果が得られました。また、ETagを使用して明示的に設定することもできません

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

アップデート:IIS7 で実行する場合、ETag ヘッダーを手動で追加することができます。これは、ASP.NET と IIS7 パイプライン間の緊密な統合が原因であると思われます。

説明:長い質問ですが、核心的な質問は次のとおりです。 ASP.NET はなぜこのようなことを行うのでしょうか?どうすれば回避できますか?また回避する必要がありますか?

アップデート:受け入れます トニーの答え それは本質的に正しいからです(トニー行け!)。HttpCacheability.Private を完全にエミュレートしたい場合は、キャッシュ可能性を ServerAndPrivate に設定できますが、呼び出しキャッシュも使用できることがわかりました。SetOmitVaryStar(true) それ以外の場合、キャッシュは 変化する:* ヘッダーを出力に追加しますが、それは望ましくありません。編集権限を取得したら、それを回答に編集します (または、この Tony を見た場合は、その呼び出しを含めるように回答を編集できますか?)

役に立ちましたか?

解決

HttpCacheability.ServerAndPrivate を使用する必要があると思います

これにより、キャッシュを制御できるようになります。ヘッダーに private を追加し、ETag を設定できるようにします。

それに関するドキュメントはもう少し改善する必要があります。

編集: Markus は、cache.SetOmitVaryStar(true) の呼び出しもあることを発見しました。そうでない場合、キャッシュは Vary を追加します。* ヘッダーを出力に追加しますが、それは望ましくありません。

他のヒント

残念ながら見てみると System.Web.HttpCachePolicy.UpdateCachedHeaders() .NET Reflector では、ETag 処理を実行する前に Cacheability が Private ではないことを特にチェックする if ステートメントがあることがわかります。いずれにせよ、私はいつもそれを見つけました Last-Modified/If-Modified-Since 私たちのデータにはうまく機能し、とにかく Fiddler で監視するのが少し簡単です。

私と同じように、ここで説明した Cacheability.ServerAndPrivate を使用する回避策に不満があり、代わりに Private を使用したい場合は、おそらくユーザーごとにページを個別にカスタマイズしており、サーバーにキャッシュするのは意味がないためです。 .NET 3.5 では、Response.Headers.Add を通じて ETag を設定でき、これは正常に機能します。

注:これを行う場合は、クライアント ヘッダーと HTTP 304 応答処理の比較を自分で実装する必要があります。通常の状況で .NET がこれを処理してくれるかどうかはわかりません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top