2013-02-12 12 views
5

W witrynie ASP.NET, chciałbym dodać nagłówek "Wygasa" do niektórych plików statycznych, więc dodałem konfigurację clientCache, taką jak ta dla folderu, w którym tych plików są:Ustawianie wartości nagłówka HTTP "wygasło" programowo w asp.net

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

Jeśli to możliwe, chciałbym obliczyć wartość httpExpires programowo, aby ustawić go na przykład do czasu ostatniej aktualizacji pliku + 24 godzin.

Czy istnieje sposób, aby skonfigurować kontrolę pamięci podręcznej, aby uzyskać wartość httpExpires, wywołując metodę?

Jeśli nie, jakie są alternatywy? Pomyślałem o napisaniu niestandardowego programu obsługi http, ale być może istnieje prostsze rozwiązanie ...

EDIT: należy pamiętać, że są to pliki statyczne, więc nie są obsługiwane przez zwykły program obsługi strony asp.net.

Odpowiedz

7

Można użyć Response.Cache do programowego ustawiania buforowania.

Here's ładnie wyglądający samouczek.

Zasadniczo chcesz ustawić politykę buforowania na Public (klienty + proxy) i ustawić nagłówek wygasania. Niektóre metody są nazywane raczej niezgrabnie, ale ten jest dość łatwy.

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

(projektanci ASP.NET nie podoba Prawo Demeter dużo, prawda?)

Alternatywnie można uzyskać dostęp do heareds poprzez Response.Headers kolekcji, w której można zmieniać je wyraźnie.

Oba te sposoby są dostępne we wszystkich programach obsługi ASP.NET (aspx, asmx) i mogą być zmieniane prawdopodobnie wszędzie, gdzie można uzyskać dostęp do bieżącego HttpContext.

+0

dzięki, ale są to pliki statyczne, mówią, że mają „xyz” rozszerzenie, więc nie są one obsługiwane przez zwykłe programy obsługi asp.net. Czy muszę napisać własną? –

+1

Och, przepraszam, ominąłem to w twoim pytaniu. W takim przypadku ** [moduł HTTP] (http://support.microsoft.com/kb/307996?wa=wsignin1.0) ** powinien być tym, czego szukasz. Jeśli tak, zaktualizuję odpowiedź –

6

Dzięki @HonzaBrestan, który umieścił mnie na właściwej ścieżce dzięki pomysłowi Modułu HTTP, wymyśliłem rozwiązanie takie jak to, które chcę udostępnić na wypadek, gdyby było przydatne dla kogoś innego.

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() { 
    } 

} 

Następnie trzeba dodać moduł w config WWW (IIS 7):

<system.webServer> 
    <modules> 
    <add name="ExpirationModule" type="ExpirationModule"/> 
    </modules> 
</system.webServer> 
Powiązane problemy