2011-02-04 8 views
5

Dla strony internetowej chcę TYLKO cacheować strony dla użytkowników, którzy nie są uwierzytelnieni - uwierzytelnieni użytkownicy nie otrzymują treści z pamięci podręcznej (ponieważ będą aktualizować i muszą widzieć wyniki poprawnie z dala).Buforowanie treści tylko dla nieuwierzytelnionych użytkowników

Umiem zmieniać cache dla każdego użytkownika z wykorzystaniem VaryByCustom: Link1 Link2

... Ale nie mogę dowiedzieć się, jak wyłączyć buforowanie całkowicie dla uwierzytelnionych użytkowników.

Co robić?

Edit

Poniższy kod ma problem jeśli istnieje już buforowane wersja strony od niezidentyfikowany użytkownik. Zasadniczo uwierzytelniony użytkownik otrzyma nieuwierzytelniony widok rzeczy.

Jednak ten link tutaj ma rozwiązanie, które działa: Link

+0

można stworzyć swój własny atrybut pamięci podręcznej, które sprawdzają, czy użytkownik jest uwierzytelniony i po zrobić jakąś logikę (cache lub nie wyjściowy cache). –

+0

Brzmi nieźle, ROBYCoNTe. Powinieneś zapisać to jako odpowiedź, aby ludzie mogli na nią głosować. :) – Kjensen

Odpowiedz

3

Użyj funkcji HttpCachePolicy.AddValidationCallback.

Patrz: http://msdn.microsoft.com/en-us/library/system.web.httpcachepolicy.addvalidationcallback.aspx

+0

Właściwie, mój utworzyłby nową wersję dla każdego żądania! Tak więc uwierzytelniony użytkownik nigdy nie powinien widzieć treści w pamięci podręcznej. Ale znowu, możesz mieć nowy problem, zanieczyszczenie pamięci podręcznej.Hmmm, pozwól mi kontynuować. Może powrót z tego będzie działał. – Haacked

0

Możesz utworzyć dwa kontrolery, jeden dla uwierzytelnionych użytkowników (gdzie nie cache), po jednym dla niezarejestrowanych użytkowników uwierzytelnionych (gdzie cache) . Następnie możesz refraktować logikę w kontrolerach do wspólnego "obiektu warstwy biznesowej", aby zachować kod DRY i testować jednostkę.

+0

To jest sposób, aby to zrobić, ale musi być lepszy sposób. – Kjensen

2

wzorując się na Link1 pan pisał, jak łatwe w kodzie Chodzi o to, że można zmienić wyjście ręcznym GetVaryByCustomString następująco:

public override string GetVaryByCustomString(HttpContext context, string arg) 
{ 
    if (arg == "IsLoggedIn") 
    { 
     if (context.Request.Cookies["anon"] != null) 
     { 
      if (context.Request.Cookies["anon"].Value == "false") 
      { 
       return "auth"; 
      } 
     } 
     return Guid.New().ToString(); 
    } 
    else 
    { 
     return base.GetVaryByCustomString(context, arg); 
    } 
} 

To naprawdę nie jest odpowiedzią, jak technicznie uwierzytelniony dane wyjściowe użytkownika będą nadal przechowywane w pamięci podręcznej, ale spełniają wymóg posiadania uwierzytelnionych użytkowników, niezależnie od wyników. Minusem jest to, że będziesz musiał utrzymywać czas buforowania/TTL wystarczająco mały, aby pamięć podręczna nie została zalana, ale wystarczająco duża, aby anonimowi użytkownicy mogli odnieść z niej korzyści.

Inną opcją jest napisanie własnego filtru akcji w celu wykonania buforowania i dodanie tam obsługi buforowania anonimowego. To jednak znacznie więcej na terytorium "zwijania własnego". Zobacz Klopfenstein's old post lub Steve Sanderson's na temat tego punktu początkowego. Brakuje im wielu innych funkcji OutputCache (na przykład kluczyków na całej trasie), ale możesz sprawić, by działał zgodnie ze swoimi własnymi specyfikacjami.

5

Użyj tego jako globalnego filtra akcji.

public class NoCacheForAuthenticatedUsersAttribute: ActionFilterAttribute 
{ 
    public override void OnResultExecuted(ResultExecutedContext filterContext) 
    { 
     if(filterContext.HttpContext.User.Identity.IsAuthenticated) 
     { 
      filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache); 
     } 
    } 
} 
+1

Wydaje się, że nie działa dla mnie. Po umieszczeniu strony w wyjściowej pamięci podręcznej logika atrybutów nie zostanie wykonana. –

+0

Być może nie znaleziono wywołania zwrotnego sprawdzania poprawności httpContext.Response.Cache.AddValidationCallback – qub1n

Powiązane problemy