it-swarm.com.de

Verhindern Sie das Zwischenspeichern in ASP.NET MVC für bestimmte Aktionen, die ein Attribut verwenden

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?

177

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).

291
mattytommo

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.

231
Jaguir

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:

OutputCache Duration=0 Response Headers: max-age=0, s-maxage=0

47
Chris Moschini

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.
13
dfortun

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;
    }
}
5
Konamiman

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());
    }
4
Davut Gürbüz

Ausgabe-Caching in MVC

 [OutputCache (NoStore = true, Dauer = 0, Location = "None", VaryByParam = "*")] 

 OR 
 [OutputCache (NoStore = true, Dauer = 0, VaryByParam = "Keiner")]

1
Deepak

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:

Antwort-Caching in ASP.NET Core - NoStore und Location.None

0
Nenad