Disabilitare la cache del browser per l'intero sito Web ASP.NET


199

Sto cercando un metodo per disabilitare la cache del browser per un intero sito Web ASP.NET MVC

Ho trovato il seguente metodo:

Response.Cache.SetCacheability(System.Web.HttpCacheability.NoCache);
Response.Cache.SetNoStore();

E anche un metodo meta tag (non funzionerà per me, poiché alcune azioni MVC inviano HTML / JSON parziale tramite Ajax, senza un head, meta tag).

<meta http-equiv="PRAGMA" content="NO-CACHE">

Ma sto cercando un metodo semplice per disabilitare la cache del browser per un intero sito Web.


Risposte:


92
HttpContext.Current.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
HttpContext.Current.Response.Cache.SetValidUntilExpires(false);
HttpContext.Current.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
HttpContext.Current.Response.Cache.SetNoStore();

Tutte le richieste vengono prima instradate attraverso default.aspx, quindi supponendo che tu possa semplicemente inserire il codice dietro.


17
Lo metterei in Global.asax.cs in Application_BeginRequest (). Non mi fido di questa cosa di default.aspx ... Un'altra domanda: ha la precedenza sugli attributi [OutputCache]?
chris166,

5
Mi piace l'idea di creare semplicemente un filtro d'azione globale e di mettere queste cose in quel modo. Annulla la necessità di preoccuparsi di Default.aspx e Global.asax.
Keith Adler,

13
Inserirlo in Application_BeingRequest può causare alcuni problemi. Se le tue immagini vengono instradate attraverso il runtime .net (cosa che può accadere se stai utilizzando la mappatura dei caratteri jolly per URL utili), allora nessuna immagine verrà memorizzata nella cache sul browser. Questo può VERAMENTE rallentare i tempi di caricamento della pagina poiché ogni richiesta di pagina scaricherà nuovamente tutte le immagini.
Herbrandson

4
L'uso di qualsiasi cosa a livello di codice avrà sempre la precedenza su qualsiasi attributo dichiarato. In altre parole, l'uso del codice OP sostituirà qualsiasi attributo [OutputCache] dichiarato.
Dave Black,

Qualche idea su come fumare test e verificare che la disabilitazione della cache funzioni davvero?
paaone,

366

Crea una classe che eredita da IActionFilter.

public class NoCacheAttribute : ActionFilterAttribute
{  
    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
        filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false);
        filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
        filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        filterContext.HttpContext.Response.Cache.SetNoStore();

        base.OnResultExecuting(filterContext);
    }
}

Quindi inserisci gli attributi dove necessario ...

[NoCache]
[HandleError]
public class AccountController : Controller
{
    [NoCache]
    [Authorize]
    public ActionResult ChangePassword()
    {
        return View();
    }
}

19
Invece di HttpContext.Current.Response, è consigliabile utilizzare filterContext.HttpContext.Response poiché HttpContext.Current restituisce l'oggetto HttpContext pre-MVC e filterContext.HttpContext restituisce HttpContextBase post-MVC. Aumenta la testabilità e la coerenza.
mkedobbs,

5
IActionFilter è già implementato su ActionFilterAttribute, quindi non è necessario ripeterlo.
Andrew Davey,

104
Nelle versioni attuali di ASP.NET MVC puoi semplicemente utilizzare OutputCacheAttribute per impedire la memorizzazione nella cache: [OutputCache (NoStore = true, Duration = 0, VaryByParam = "None")]
Ashley Tate

9
Vorrei sottolineare che ho appena trascorso diversi giorni utilizzando ogni soluzione "inserisci questo nel tuo codice per interrompere la memorizzazione nella cache" sotto il sole per ASP.NET MVC, inclusa la risposta accettata a questa domanda, senza alcun risultato. Questa risposta - l'attributo - ha funzionato. + 1M rappresentante se potessi ...
Tom Kidd,

5
Potresti voler aggiungere if (filterContext.IsChildAction) return;in alto: questo eviterà che l'azione esterna sia "nessuna cache" se chiama un'azione figlio decorata con NoCacheattributo. In altre parole, l' NoCacheattributo non passerà ad altre azioni se eseguono azioni secondarie. Inoltre, il nome della classe dovrebbe essere NoCacheAttributeconforme alla convenzione di denominazione generalmente accettata per gli attributi.
Jakub Konecki,

132

Invece di creare il tuo, usa semplicemente quello che ti viene fornito.

Come accennato in precedenza, non disabilitare la memorizzazione nella cache per tutto. Ad esempio, gli script jQuery utilizzati pesantemente in ASP.NET MVC devono essere memorizzati nella cache. In realtà idealmente dovresti usare un CDN per quelli comunque, ma il mio punto è che alcuni contenuti dovrebbero essere memorizzati nella cache.

Quello che trovo funziona meglio qui piuttosto che spargere ovunque [OutputCache] è usare una classe:

[System.Web.Mvc.OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public class NoCacheController  : Controller
{
}

Tutti i controller che si desidera disabilitare per la memorizzazione nella cache quindi ereditare da questo controller.

Se è necessario sovrascrivere i valori predefiniti nella classe NoCacheController, è sufficiente specificare le impostazioni della cache sul metodo di azione e le impostazioni sul metodo di azione avranno la precedenza.

[HttpGet]
[OutputCache(NoStore = true, Duration = 60, VaryByParam = "*")]
public ViewResult Index()
{
  ...
}

4
@Ozziepeeps, il tuo commento non è corretto. I documenti msdn descrivono la memorizzazione nella cache del browser e un semplice test mostrerà che questo attributo modifica l'intestazione della risposta del controllo cache in "Controllo cache: pubblico, no-store, max-age = 0" da "Controllo cache: privato" senza usando l'attributo.
Adam Tuliper - MSFT,

2
Inoltre, puoi controllare tutte e tre le posizioni (server, proxy, client) con questo attributo in modo da poter controllare oltre la cache del server. Vedi asp.net/mvc/tutorials/… per alcuni dettagli aggiuntivi.
Adam Tuliper - MSFT,

1
+1 "Se devi sovrascrivere i valori predefiniti nella classe NoCacheController, specifica semplicemente le impostazioni della cache sul tuo metodo di azione e le impostazioni sul tuo metodo di azione avranno la precedenza."
Korayem,

2
Nota che se usi [System.Web.Mvc.OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]a livello di classe, non puoi avere PartialView nella tua classe.
Fiume Vivian,

1
Il metodo OutputCache non ha impedito la memorizzazione nella cache di IE in presenza di due condizioni: 1) l'azione non ha preso parametri e 2) l'azione ha restituito solo testo tramite Content (someText). Quando restituisco JSON e prendo un parametro, la memorizzazione nella cache di IE viene correttamente eliminata.
Kasey Speakman,

10

È possibile disabilitare la memorizzazione nella cache del browser per tutte le pagine visualizzate dai controller (ad esempio pagine HTML), ma mantenere la memorizzazione nella cache in atto per risorse quali script, fogli di stile e immagini . Se stai utilizzando MVC4 + raggruppamento e minificazione, ti consigliamo di mantenere le durate della cache predefinite per script e fogli di stile (durate molto lunghe, poiché la cache viene invalidata in base alla modifica di un URL univoco, non basato sul tempo).

In MVC4 +, per disabilitare la memorizzazione nella cache del browser su tutti i controller, ma conservarlo per tutto ciò che non è servito da un controller, aggiungere questo a FilterConfig.RegisterGlobalFilters:

filters.Add(new DisableCache());

Definire DisableCachecome segue:

class DisableCache : ActionFilterAttribute
{
    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
    }
}

Sfortunatamente questo non sembra funzionare, poiché premendo il pulsante Indietro dopo un logout viene visualizzata la pagina.
ᴍᴀᴛᴛ ʙᴀᴋᴇʀ

6

So che questa risposta non è correlata al 100% alla domanda, ma potrebbe aiutare qualcuno.

Se si desidera disabilitare la cache del browser per l' intero sito Web ASP.NET MVC , ma si desidera farlo solo TEMPORANEAMENTE, è meglio disabilitare la cache nel browser.

Ecco uno screenshot in Chrome


Questo è esattamente quello che stavo cercando ... durante lo sviluppo, se cambio un file .js, è molto doloroso che ciò avvenga immediatamente quando ho difficoltà a fare piccoli cicli di risoluzione dei problemi / aggiornamento / test. Questo è perfetto, grazie! Ho appena semplificato la vita del mio debug lato client
jleach,

2

Ho implementato tutte le risposte precedenti e avevo ancora una vista che non funzionava correttamente.

Si è scoperto che il nome della vista con cui avevo il problema si chiamava "Recenti". Apparentemente questo ha confuso il browser Internet Explorer.

Dopo aver modificato il nome della vista (nel controller) con un nome diverso (ho scelto "Recente5"), le soluzioni sopra hanno iniziato a funzionare.


0

Puoi provare sotto il codice nel file Global.asax.

protected void Application_BeginRequest()
    {
        Response.Cache.SetCacheability(HttpCacheability.NoCache);
        Response.Cache.SetExpires(DateTime.UtcNow.AddHours(-1));
        Response.Cache.SetNoStore();
    }

-1

UI

<%@ OutPutCache Location="None"%>
<%
    Response.Buffer = true;
    Response.Expires = -1;
    Response.ExpiresAbsolute = System.DateTime.Now.AddSeconds(-1);
    Response.CacheControl = "no-cache";
%>

sfondo

Context.Response.Cache.SetCacheability(HttpCacheability.NoCache); 
Response.Expires = -1;          
Response.Cache.SetNoStore();

1
necessita di prosa esplicativa, anche se tecnicamente corretta
rmalayter
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.