Deaktivieren Sie den Browser-Cache für die gesamte ASP.NET-Website

199

Ich suche nach einer Methode zum Deaktivieren des Browser-Caches für eine gesamte ASP.NET MVC-Website

Ich habe folgende Methode gefunden:

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

Und auch eine Meta-Tag-Methode (funktioniert bei mir nicht, da einige MVC-Aktionen teilweise HTML / JSON über Ajax senden, ohne Kopf, Meta-Tag).

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

Ich suche jedoch nach einer einfachen Methode, um den Browser-Cache für eine gesamte Website zu deaktivieren.

Palani
quelle

Antworten:

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();

Alle Anfragen werden zuerst über default.aspx geleitet - vorausgesetzt, Sie können einfach den Code dahinter einfügen.

Squiggs.
quelle
17
Ich würde es in Global.asax.cs in Application_BeginRequest () einfügen. Ich vertraue dieser default.aspx-Sache nicht ... Eine andere Frage: Hat dies Vorrang vor [OutputCache] -Attributen?
Chris166
5
Ich mag die Idee, einfach einen globalen Aktionsfilter zu erstellen und dieses Zeug auf diese Weise zu platzieren. Negiert die Notwendigkeit, sich um Default.aspx und Global.asax zu sorgen.
Keith Adler
13
Das Einfügen in Application_BeingRequest kann einige Probleme verursachen. Wenn Ihre Bilder durch die .net-Laufzeit geleitet werden (was passieren kann, wenn Sie Wildcard-Mapping für nette URLs verwenden), werden keine Bilder im Browser zwischengespeichert. Dies kann die Ladezeiten Ihrer Seite WIRKLICH verlangsamen, da bei jeder Seitenanforderung alle Bilder erneut heruntergeladen werden.
Herbrandson
4
Die programmgesteuerte Verwendung überschreibt immer alle deklarierten Attribute. Mit anderen Worten, die Verwendung des OP-Codes überschreibt alle deklarierten [OutputCache] -Attribute.
Dave Black
Irgendwelche Gedanken darüber, wie man einen Rauchtest macht und überprüft, ob die Cache-Deaktivierung tatsächlich funktioniert?
Paaone
366

Erstellen Sie eine Klasse, die von IActionFilter erbt.

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);
    }
}

Dann setzen Sie Attribute wo nötig ...

[NoCache]
[HandleError]
public class AccountController : Controller
{
    [NoCache]
    [Authorize]
    public ActionResult ChangePassword()
    {
        return View();
    }
}
JKG
quelle
19
Anstelle von HttpContext.Current.Response sollten Sie wahrscheinlich filterContext.HttpContext.Response verwenden, da HttpContext.Current das HttpContext-Objekt vor MVC und filterContext.HttpContext die HttpContextBase nach MVC zurückgibt. Es erhöht die Testbarkeit und Konsistenz.
mkedobbs
5
IActionFilter ist bereits im ActionFilterAttribute implementiert, sodass Sie es nicht wiederholen müssen.
Andrew Davey
104
In aktuellen Versionen von ASP.NET MVC können Sie einfach OutputCacheAttribute verwenden, um das Caching zu verhindern: [OutputCache (NoStore = true, Duration = 0, VaryByParam = "None")]
Ashley Tate
9
Ich möchte darauf hinweisen, dass ich nur einige Tage damit verbracht habe, jede Lösung für ASP.NET MVC, einschließlich der akzeptierten Antwort auf diese Frage, vergeblich zu verwenden, um das Caching in Ihrem Code zu beenden, einschließlich der akzeptierten Antwort auf diese Frage. Diese Antwort - das Attribut - hat funktioniert. + 1M Repräsentant, wenn ich könnte ...
Tom Kidd
5
Möglicherweise möchten Sie if (filterContext.IsChildAction) return;oben hinzufügen. Dadurch wird verhindert, dass die äußere Aktion nicht zwischengespeichert wird, wenn eine untergeordnete Aktion aufgerufen wird, die mit NoCacheAttributen versehen ist. Mit anderen Worten, das NoCacheAttribut wird nicht an andere Aktionen weitergegeben, wenn sie untergeordnete Aktionen ausführen. Außerdem sollte der Klassenname der NoCacheAttributeallgemein anerkannten Namenskonvention für Attribute entsprechen.
Jakub Konecki
132

Verwenden Sie einfach das, was für Sie bereitgestellt wird, anstatt Ihre eigenen zu rollen.

Deaktivieren Sie, wie bereits erwähnt, das Caching nicht für alles. Beispielsweise sollten in ASP.NET MVC häufig verwendete jQuery-Skripts zwischengespeichert werden. Eigentlich sollten Sie im Idealfall sowieso ein CDN für diese verwenden, aber mein Punkt ist, dass einige Inhalte zwischengespeichert werden sollten.

Was ich hier am besten finde, anstatt den [OutputCache] überall zu verteilen, ist die Verwendung einer Klasse:

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

Alle Ihre Controller, für die Sie das Caching deaktivieren möchten, erben dann von diesem Controller.

Wenn Sie die Standardeinstellungen in der NoCacheController-Klasse überschreiben müssen, geben Sie einfach die Cache-Einstellungen Ihrer Aktionsmethode an. Die Einstellungen Ihrer Aktionsmethode haben Vorrang.

[HttpGet]
[OutputCache(NoStore = true, Duration = 60, VaryByParam = "*")]
public ViewResult Index()
{
  ...
}
Adam Tuliper - MSFT
quelle
4
@ Ozziepeeps, dein Kommentar ist nicht korrekt. In den msdn-Dokumenten wird das Browser-Caching erläutert. Ein einfacher Test zeigt, dass dieses Attribut den Cache-Control-Antwortheader von "Cache-Control: Private" ohne in "Cache-Control: public, no-store, max-age = 0" ändert mit dem Attribut.
Adam Tuliper - MSFT
2
auch fyi - Sie können alle drei Standorte (Server, Proxy, Client) mit diesem Attribut steuern, sodass Sie absolut über den Server-Cache hinaus steuern können. Weitere Informationen finden Sie unter asp.net/mvc/tutorials/… .
Adam Tuliper - MSFT
1
+1 "Wenn Sie die Standardeinstellungen in der NoCacheController-Klasse überschreiben müssen, geben Sie einfach die Cache-Einstellungen Ihrer Aktionsmethode an. Die Einstellungen Ihrer Aktionsmethode haben Vorrang."
Korayem
2
Bitte beachten Sie, dass [System.Web.Mvc.OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]PartialViews in Ihrer Klasse nicht vorhanden sein können , wenn Sie sie auf Klassenebene verwenden.
Vivian River
1
Die OutputCache-Methode hat das IE-Caching nicht verhindert, wenn zwei Bedingungen vorhanden waren: 1) Die Aktion hat keine Parameter angenommen und 2) Die Aktion hat nur Text über Content (someText) zurückgegeben. Wenn ich JSON zurückgebe und einen Parameter nehme, wird das IE-Caching ordnungsgemäß deaktiviert.
Kasey Speakman
10

Möglicherweise möchten Sie das Browser-Caching für alle von Controllern gerenderten Seiten (z. B. HTML-Seiten) deaktivieren, das Caching für Ressourcen wie Skripte, Stylesheets und Bilder jedoch beibehalten . Wenn Sie die Bündelung und Minimierung von MVC4 + verwenden, sollten Sie die Standard-Cache-Dauer für Skripte und Stylesheets beibehalten (sehr lange Dauer, da der Cache aufgrund einer Änderung einer eindeutigen URL ungültig wird, nicht basierend auf der Zeit).

Fügen Sie in MVC4 + Folgendes hinzu, um das Browser-Caching auf allen Controllern zu deaktivieren, es jedoch für alle Elemente beizubehalten, die nicht von einem Controller bereitgestellt werden FilterConfig.RegisterGlobalFilters:

filters.Add(new DisableCache());

Definieren Sie DisableCachewie folgt:

class DisableCache : ActionFilterAttribute
{
    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
    }
}
Edward Brey
quelle
Leider scheint dies nicht zu funktionieren, da das Drücken der Zurück-Taste nach dem Abmelden die Seite anzeigt.
ᴍᴀᴛᴛ ʙᴀᴋᴇʀ
6

Ich weiß, dass diese Antwort nicht zu 100% mit der Frage zusammenhängt, aber sie könnte jemandem helfen.

Wenn Sie den Browser-Cache für die gesamte ASP.NET MVC-Website deaktivieren möchten, dies jedoch nur VORÜBERGEHEND tun möchten, ist es besser, den Cache in Ihrem Browser zu deaktivieren.

Hier ist ein Screenshot in Chrome

Carlos Martinez T.
quelle
Dies ist genau das, wonach ich gesucht habe ... Wenn ich während der Entwicklung eine .js-Datei ändere, ist es ein großer Schmerz, diese sofort durchzuhalten, wenn ich Probleme habe, kleine Fehlerbehebungs- / Aktualisierungs- / Testzyklen durchzuführen. Das ist perfekt, danke! Ich habe gerade das Debuggen auf meiner Client-Seite
erheblich
2

Ich habe alle vorherigen Antworten implementiert und hatte immer noch eine Ansicht, die nicht richtig funktionierte.

Es stellte sich heraus, dass der Name der Ansicht, mit der ich das Problem hatte, "Zuletzt verwendet" war. Anscheinend hat dies den Internet Explorer-Browser verwirrt.

Nachdem ich den Ansichtsnamen (im Controller) in einen anderen Namen geändert hatte (ich habe 'Recent5' gewählt), begannen die oben genannten Lösungen zu funktionieren.

DrHooverCraft
quelle
0

Sie können den folgenden Code in der Datei Global.asax ausprobieren.

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

Benutzeroberfläche

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

Hintergrund

Context.Response.Cache.SetCacheability(HttpCacheability.NoCache); 
Response.Expires = -1;          
Response.Cache.SetNoStore();
Alpha
quelle
1
braucht erklärende Prosa, auch wenn es technisch korrekt ist
Rmalayter