2016-07-27 7 views
0

Kann ich Ausgabe Caching in Seiten, die ich in Code erkennen kann, wenn Session ["Benutzer"] ist Null oder nicht, und Cache die Seite für 5 Minuten, wenn es noch nicht im Cache gespeichert ist (Ausgabe-Caching nicht abgelaufen) und und die Sitzung ["Benutzer"] == null.Ausgabe-Cache-Code für Nicht-Sitzung Benutzer

Ich möchte keinen benutzerdefinierten Ausgabecache verwenden, da er auch für angemeldete Benutzer zwischengespeichert wird. Auf diese Weise sehen nur anonyme Besucher eine zwischengespeicherte, Seite, und angemeldete Benutzer erhalten die nicht zwischengespeicherten

Ich mache dies, weil einige meiner Seiten anders aussieht, wenn der Benutzer angemeldet ist oder nicht. Ich möchte, dass Crawler und normale Besucher die Originalseite sehen und keine privaten Daten von einem Benutzer erhalten, der versehentlich das Caching ausgelöst hat.

Wie kann ich dies in Code hinter C# tun?

+0

Sie sollten 'GetVaryByCustomString' verwenden. Werfen Sie einen Blick auf diese http: //blog.danielcorreia.net/asp-net-mvc-variieren-durch-aktuelle-benutzer/http://stackoverflow.com/questions/1043112/programatically-control-output-caching-disable-or-enable-cache-according-to-pa – smoksnes

+0

@smoksnes, aber das wird einen Cache für jeden Benutzer erstellen, richtig? –

+0

Ja, du hast Recht. Mein Fehler. – smoksnes

Antwort

1

Sie sollten eine benutzerdefinierte OutputCacheProvider erstellen können.

In Ihrer global.asax:

public override string GetOutputCacheProviderName(HttpContext context) 
    { 
     bool isInSession = true; // Determine here. 
     if (isInSession) 
     { 
      return "CustomProvider"; 
     } 

     // Or by page: 
     if (context.Request.Path.EndsWith("MyPage.aspx")) 
     { 
      return "SomeOtherProvider"; 
     } 

     return base.GetOutputCacheProviderName(context); 
    } 

Dann Ihren Provider erstellen:

public class SessionBasedCacheProvider : OutputCacheProvider 
{ 
    public override object Get(string key) 
    { 
     return null; // Do not cache. 
    } 

    public override object Add(string key, object entry, DateTime utcExpiry) 
    { 
     // Basically let it "fall through" since we don't want any caching. 
     return entry; 
    } 

    public override void Set(string key, object entry, DateTime utcExpiry) 
    { 
     // Basically let it "fall through" since we don't want any caching.    
    } 

    public override void Remove(string key) 
    { 
     // Basically let it "fall through" since we don't want any caching. 
    } 
} 

von null von Set Rückkehr, werden Sie nicht die Elemente zwischenspeichern.

Der Schlüsselwert, der den angegebenen Eintrag im Cache identifiziert, oder null, wenn der angegebene Eintrag nicht im Cache vorhanden ist.

und fügen Sie Ihren Anbieter für die config:

<system.web> 
    <caching> 
     <outputCache defaultProvider="AspNetInternalProvider"> 
     <providers> 
      <clear/> 
      <add name="CustomProvider" type="YourNamespace.SessionBasedCacheProvider, YourNamespace, Version=1.0.0.0, Culture=neutral"/> 
     </providers> 
     </outputCache> 
    </caching> 
</web> 

es möglich ist, sollten Sie in der Lage sein zu verwenden. Setzen Sie dies einfach an den Anfang der ASPX-Seite. Beachten Sie das Attribut Location, abhängig davon, wo Sie es zwischenspeichern möchten.

<%@ OutputCache Duration="60" VaryByParam="None" Location="Server" %> 

https://msdn.microsoft.com/en-us/library/hdxfb6cy(v=vs.85).aspx

https://msdn.microsoft.com/en-us/magazine/gg650661.aspx

Alternativ verwenden Sie können immer den gleichen CacheProvider, und lassen Sie es festzustellen, ob das Element im Cache gespeichert werden soll oder nicht.

public class CustomOutputCacheProvider : OutputCacheProvider 
{ 
    public override object Add(string key, object entry, DateTime utcExpiry) 
    { 
     // Determine if in session. 
     bool isInSession = true; 
     if (isInSession) 
     { 
      return null; 
     } 

     // Do the same custom caching as you did in your 
     // CustomMemoryCache object 
     var result = HttpContext.Current.Cache.Get(key); 

     if (result != null) 
     { 
      return result; 
     } 

     HttpContext.Current.Cache.Add(key, entry, null, utcExpiry, 
      System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Normal, null); 

     return entry; 
    } 

    public override object Get(string key) 
    { 
     return HttpContext.Current.Cache.Get(key); 
    } 

    public override void Remove(string key) 
    { 
     HttpContext.Current.Cache.Remove(key); 
    } 

    public override void Set(string key, object entry, DateTime utcExpiry) 
    { 
     HttpContext.Current.Cache.Add(key, entry, null, utcExpiry, 
      System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Normal, null); 
    } 
} 

-Code von http://www.haneycodes.net/custom-output-caching-with-mvc3-and-net-4-0-done-right/

Hinweis, ich habe nicht getestet mit Session, aber in der Theorie sollte es funktionieren. Aber ich schlage vor, dass Sie es wirklich testen, bevor Sie es veröffentlichen. Caching ist immer viel schwieriger, als man denken ... :(

UPDATE:. Seit Session ist nicht verfügbar, sollten Sie ein Cookie zu verwenden, anstatt der Lage sein

protected void Session_Start(object sender, EventArgs e) 
{ 
    Response.Cookies.Add(new HttpCookie("SessionCookie", "some_value")); 
} 

public override string GetOutputCacheProviderName(HttpContext context) 
{ 
    bool isInSession = true; // Determine here. 

    if (context.Request.Cookies["SessionCookie"] != null) 
    { 
     // Use your CustomProvider 
    } 

    if (isInSession) 
    { 
     return "CustomProvider"; 
    } 

    // Or by page: 
    if (context.Request.Path.EndsWith("MyPage.aspx")) 
    { 
     return "SomeOtherProvider"; 
    } 

    return base.GetOutputCacheProviderName(context); 
} 

Denken Sie daran, das löschen Cookie, oder behandeln Sie es in irgendeiner Weise.

+0

Danke. Was lege ich in die Seite, auf der ich diesen benutzerdefinierten Outputcache verwenden möchte? –

+0

Wenn ich den zweiten Code ("selbe CacheProvider",) verwende, kann ich die geänderte aus der web.config entfernen? –

+0

Ich habe meine Antwort aktualisiert. Sie müssen es jedoch weiterhin in web.config registrieren. Sonst findet .NET Ihren Provider nicht namentlich. Beachten Sie, dass es sich um den Namen ' smoksnes