Ich habe eine ASP.NET MVC 3-Anwendung. Diese Anwendung fordert Datensätze über JQuery an. JQuery ruft eine Controller-Aktion zurück, die Ergebnisse im JSON-Format zurückgibt. Ich konnte das nicht beweisen, aber ich mache mir Sorgen, dass meine Daten möglicherweise zwischengespeichert werden.
Ich möchte, dass das Caching nur für bestimmte Aktionen gilt, nicht für alle Aktionen.
Gibt es ein Attribut, mit dem ich eine Aktion vornehmen kann, um sicherzustellen, dass die Daten nicht zwischengespeichert werden? Wenn nicht, wie kann ich sicherstellen, dass der Browser jedes Mal einen neuen Satz Datensätze anstelle eines zwischengespeicherten Satzes erhält?
Um sicherzustellen, dass JQuery die Ergebnisse nicht zwischenspeichert, geben Sie in Ihre Ajax-Methoden Folgendes ein:
$.ajax({
cache: false
//rest of your ajax setup
});
Oder um das Zwischenspeichern in MVC zu verhindern, haben wir unser eigenes Attribut erstellt. Sie könnten dasselbe tun. Hier ist unser Code:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed 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 schmücken Sie einfach Ihren Controller mit [NoCache]
. OR Um das alles zu tun, können Sie das Attribut einfach der Klasse der Basisklasse zuordnen, von der Sie Ihre Controller erben (falls vorhanden), wie hier:
[NoCache]
public class ControllerBase : Controller, IControllerBase
Sie können einige der Aktionen auch mit diesem Attribut versehen, wenn sie nicht zwischengespeichert werden können, anstatt den gesamten Controller zu dekorieren.
Wenn Ihre Klasse oder Aktion nicht NoCache
hatte, als sie in Ihrem Browser gerendert wurde und Sie überprüfen möchten, dass sie funktioniert, müssen Sie daran denken, dass Sie nach dem Kompilieren der Änderungen eine "harte Aktualisierung" (Strg + F5) in Ihrem Browser durchführen müssen. Bis Sie dies tun, behält Ihr Browser die alte zwischengespeicherte Version bei und aktualisiert diese nicht mit einer "normalen Aktualisierung" (F5).
Sie können das eingebaute Cache-Attribut verwenden, um das Caching zu verhindern.
Für .net Framework: [OutputCache(NoStore = true, Duration = 0)]
Für .net Core: [ResponseCache(NoStore = true, Duration = 0)]
Beachten Sie, dass der Browser das Zwischenspeichern nicht deaktivieren kann. Das Beste, was Sie tun können, ist Vorschläge zu machen, die von den meisten Browsern berücksichtigt werden, normalerweise in Form von Kopfzeilen oder Meta-Tags. Dieses Decorator-Attribut deaktiviert das Server-Caching und fügt außerdem den folgenden Header hinzu: Cache-Control: public, no-store, max-age=0
. Es werden keine Metatags hinzugefügt. Falls gewünscht, können diese manuell in der Ansicht hinzugefügt werden.
Darüber hinaus versuchen JQuery und andere Client-Frameworks, den Browser dazu zu überreden, die zwischengespeicherte Version einer Ressource nicht zu verwenden, indem er der URL Zeug hinzufügt, z. Dies bewirkt, dass der Browser erneut nach der Ressource fragt, verhindert jedoch nicht wirklich das Zwischenspeichern.
Zum Schluss noch eine Anmerkung. Sie sollten wissen, dass Ressourcen auch zwischen Server und Client zwischengespeichert werden können. ISPs, Proxies und andere Netzwerkgeräte zwischenspeichern auch Ressourcen und verwenden häufig interne Regeln, ohne sich die tatsächliche Ressource anzusehen. Sie können nicht viel dagegen tun. Die gute Nachricht ist, dass sie normalerweise für kürzere Zeitrahmen wie Sekunden oder Minuten cachen.
Alles was Sie brauchen ist:
[OutputCache(Duration=0)]
public JsonResult MyAction(
oder, wenn Sie es für einen gesamten Controller deaktivieren möchten:
[OutputCache(Duration=0)]
public class MyController
Trotz der Debatte in den Kommentaren reicht dies aus, um das Browser-Caching zu deaktivieren. Dadurch sendet ASP.Net Antwort-Header, die dem Browser mitteilen, dass das Dokument sofort abläuft:
Hängen Sie in der Controller-Aktion die folgenden Zeilen an die Kopfzeile an
public ActionResult Create(string PositionID)
{
Response.AppendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
Response.AppendHeader("Pragma", "no-cache"); // HTTP 1.0.
Response.AppendHeader("Expires", "0"); // Proxies.
Hier ist das von mattytommo vorgeschlagene NoCache
-Attribut, vereinfacht durch Verwendung der Informationen aus der Antwort von Chris Moschini:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class NoCacheAttribute : OutputCacheAttribute
{
public NoCacheAttribute()
{
this.Duration = 0;
}
}
Für MVC6 (DNX) gibt es keinen System.Web.OutputCacheAttribute
Hinweis: Wenn Sie NoStore
Duration einstellen, wird der Parameter nicht berücksichtigt. Es ist möglich, eine Anfangsdauer für die Erstregistrierung festzulegen und diese mit benutzerdefinierten Attributen zu überschreiben.
Aber wir haben Microsoft.AspNet.Mvc.Filters.ResponseCacheFilter
public void ConfigureServices(IServiceCollection services)
...
services.AddMvc(config=>
{
config.Filters.Add(
new ResponseCacheFilter(
new CacheProfile() {
NoStore=true
}));
}
...
)
Es ist möglich, den ursprünglichen Filter mit einem benutzerdefinierten Attribut zu überschreiben
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class NoCacheAttribute : ActionFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
var filter=filterContext.Filters.Where(t => t.GetType() == typeof(ResponseCacheFilter)).FirstOrDefault();
if (filter != null)
{
ResponseCacheFilter f = (ResponseCacheFilter)filter;
f.NoStore = true;
//f.Duration = 0;
}
base.OnResultExecuting(filterContext);
}
}
Hier ist ein Anwendungsfall
[NoCache]
[HttpGet]
public JsonResult Get()
{
return Json(new DateTime());
}
Ausgabe-Caching in MVC
[OutputCache (NoStore = true, Dauer = 0, Location = "None", VaryByParam = "*")] OR [OutputCache (NoStore = true, Dauer = 0, VaryByParam = "Keiner")]
Der korrekte Attributwert für Asp.Net MVC Core zum Verhindern des Browser-Caching (einschließlich Internet Explorer 11) lautet:
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
wie in der Microsoft-Dokumentation beschrieben: