5

ASP.NETサイトで、特定の静的ファイルに「Expires」ヘッダーを追加したいのでclientCache、これらのファイルがあるフォルダーに次のような構成を追加しました。

<system.webServer>
  <staticContent>
    <clientCache cacheControlMode="UseExpires" httpExpires="Wed, 13 Feb 2013 08:00:00 GMT" />
  </staticContent>

可能であれば、httpExpiresプログラムでの値を計算して、たとえばファイルが最後に更新された時刻+24時間に設定したいと思います。

httpExpiresメソッドを呼び出しての値を取得するようにキャッシュコントロールを構成する方法はありますか?

そうでない場合、代替手段は何ですか?カスタムhttpハンドラーを作成することを考えましたが、もっと簡単な解決策があるかもしれません...

編集:これらは静的ファイルであるため、通常のasp.netページハンドラーによって提供されないことに注意してください。

4

2 に答える 2

7

Response.Cacheプログラムでキャッシュを設定するために使用できます。

これは見栄えの良いチュートリアルです。

基本的に、キャッシュ ポリシーをPublic(クライアント側 + プロキシ) に設定し、有効期限ヘッダーを設定します。一部のメソッドはややぎこちなく名前が付けられていますが、これは簡単です。

HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.Public);
HttpContext.Current.Response.Cache.SetExpires(yourCalculatedDateTime);

(ASP.NET の設計者は、デメテルの法則があまり好きではありませんでしたね?)

または、コレクションを介してヒアリングにアクセスし、Response.Headers明示的に変更することもできます。

これらの方法はどちらも、すべての ASP.NET ハンドラー (aspx、asmx) でアクセスでき、現在の HttpContext にアクセスできる場所ならどこでも変更できます。

于 2013-02-12T16:31:04.430 に答える
6

HTTPモジュールのアイデアで私を正しい軌道に乗せてくれた@HonzaBrestanのおかげで、私はこのような解決策を思いつきました.

using System;
using System.Collections.Generic;
using System.IO;
using System.Web;

public class ExpirationModule : IHttpModule {

    HttpApplication _context;

    #region static initialization for this example - this should be a config section

    static Dictionary<string, TimeSpan> ExpirationTimes;
    static TimeSpan DefaultExpiration = TimeSpan.FromMinutes(15);
    static CrlExpirationModule() {       
        ExpirationTimes = new Dictionary<string, TimeSpan>();
        ExpirationTimes["~/SOMEFOLDER/SOMEFILE.XYZ"] = TimeSpan.Parse("0.0:30");
        ExpirationTimes["~/ANOTHERFOLDER/ANOTHERFILE.XYZ"] = TimeSpan.Parse("1.1:00");
    }

    #endregion

    public void Init(HttpApplication context) {
        _context = context;
        _context.EndRequest += ContextEndRequest;
    }

    void ContextEndRequest(object sender, EventArgs e) {
        // don't use Path as it contains the application name
        string requestPath = _context.Request.AppRelativeCurrentExecutionFilePath;
        string expirationTimesKey = requestPath.ToUpperInvariant();
        if (!ExpirationTimes.ContainsKey(expirationTimesKey)) {
            // not a file we manage
            return;
        }
        string physicalPath = _context.Request.PhysicalPath;
        if (!File.Exists(physicalPath)) {
            // we do nothing and let IIS return a regular 404 response
            return;
        }
        FileInfo fileInfo = new FileInfo(physicalPath);
        DateTime expirationTime = fileInfo.LastWriteTimeUtc.Add(ExpirationTimes[expirationTimesKey]);
        if (expirationTime <= DateTime.UtcNow) {
            expirationTime = DateTime.UtcNow.Add(DefaultExpiration);
        }
        _context.Response.Cache.SetExpires(expirationTime);
    }

    public void Dispose() {
    }

}

次に、Web 構成 (IIS 7) にモジュールを追加する必要があります。

<system.webServer>
  <modules>
    <add name="ExpirationModule" type="ExpirationModule"/>
  </modules>
</system.webServer>
于 2013-02-13T13:21:22.770 に答える