2011-01-29 10 views
5

Mam pytanie, w jaki sposób programowo nakazać programowi ASP.NET pominięcie rozwiązania żądania z pamięci podręcznej wyników.Warunkowe buforowanie danych wyjściowych w środowisku ASP.NET

Wyobraź sobie, że masz buforowane dane wyjściowe strony (na przykład http://domain/page.aspx) za pomocą zastosowania ustawień zasad pamięci podręcznej z CMS do HttpResponse w czasie wykonywania. Na na podstawie żądania w zależności od np. Bieżący użytkownik jest uwierzytelniony + członek zestawu znanych grup (lub dopasowany przez logikę biznesową), chciałbym polecić ASP.NET do pomiń rozwiązywanie żądania z wyjściem Pamięć podręczna.

Scenariusz zakłada, że ​​w systemie jednocześnie jest dwóch różnych użytkowników (lub więcej). Użytkownik A jest uwierzytelniony + członek zbioru znanych grup, a użytkownik B jest anonimowy. Niezależnie od strony, która jest zapisywana w pamięci podręcznej, chcę, aby uwierzytelniony użytkownik przeglądał wszystkie strony tak, jakby nie włączono buforowania wyjściowego - nigdy; jednocześnie chciałbym, aby środowisko ASP.NET nadal wyświetlało wyjściowe strony z pamięci podręcznej anonimowym użytkownikom (lub użytkownikom, którzy nie są zgodni z logiką biznesową).

Typową sugestią jest używanie VaryByHeader, VaryByParam itd. I zanieczyszczanie wyjściowej pamięci podręcznej - niedobrze, ale podczas kopania modułu wyjściowego cache za pomocą Reflectora, zauważyłem, że wyjściowy moduł pamięci podręcznej pomija bieżące żądanie w przypadku, gdy para znanych nagłówków "cache-control" są obecne. Jeśli chodzi o nagłówki, są one wysyłane z przeglądarki, jeśli użytkownik wymusza wyświetlenie nowej kopii, naciskając klawisz F5 lub ENTER na pasku adresu.

Po prostu ustawiam nagłówek "cache-control" na "no-cache" w niestandardowym module http w zdarzeniu poprzedzającym zdarzenie ResolveRequestCache, do którego subskrybuje wyjściowy bufor. Tak:

context.Request.Headers["Cache-Control"] = "no-cache"; 

Wszystko jest ładne i dandys, jednakże jeśli HttpCachePolicy.SetValidUntilExpires polityka (true) cache jest ustawiony, ASP.NET pomija nagłówek żądania wcześniej ustawiony i służy wniosek cache wyjściowego.

Jako alternatywę, myślę, że mógłbym napisać dodatkowy kod w zdarzeniu przetwarzania końcowego w tym samym module http, aby zapewnić wywołanie funkcji HttpCachePolicy.SetValidUntilExpires (false), na wypadek gdyby buforowanie wyjściowe zostało skonfigurowane, ale myślę, że byłby bardziej czystym rozwiązaniem, aby móc instruować ASP.NET, aby po prostu pominął rozwiązywanie żądania z wyjściowej pamięci podręcznej. Mogę sobie wyobrazić wiele rozwiązań na to pytanie, ale szukam właściwego.

Dla porównania, staram większość jeśli nie wszystkie odpowiednie metody klasy HttpCachePolicy np .:

HttpResponse.Cache.SetNoServerCaching()). 

Odpowiedz

3

Możesz dodać HttpCacheValidateHandler do swojej aplikacji, w której możesz zaimplementować dowolną logikę. Zostanie ono wykonane podczas zdarzenia ResolveRequestCache, które jest uruchamiane po wykonaniu uwierzytelniania i autoryzacji. Kluczem jest zwrócenie HttpValidationStatus.IgnoreThisRequest w przypadku, gdy chcesz ominąć pamięć podręczną.

Zobacz tę próbkę HttpModule dla odniesienia:

public class CacheModule : IHttpModule 
{ 
    public void Init(HttpApplication context) 
    { 
     context.BeginRequest += 
      (s, e) => context.Context.Response.Cache 
         .AddValidationCallback(CacheHandler, null); 
    } 

    private static void CacheHandler(
     HttpContext context, object data, 
     ref HttpValidationStatus validationstatus) 
    { 
     // bypass cache for all users with skipCache cookie 
     validationstatus = 
      context.Request.Cookies["skipCache"] != null 
       ? HttpValidationStatus.IgnoreThisRequest 
       : HttpValidationStatus.Valid; 
    } 

    public void Dispose() 
    { 
    } 
} 
+0

Oliver, nigdy nie jest za późno i dziękuje dla odpowiedzi, którą mam teraz zaimplementowałem Zastanawiam się, jak mogłem przegapić ** metodę AddValidationCallback **. znowu, co jest ważne praca z frameworkiem, co zresztą przeoczyłem przy poprzedniej implementacji. –

0

nie jestem pewien, czy jest obsługiwana metoda robi to po coś są buforowane.

Ale dlaczego nie lubisz opcji VaryByHeader? Zakładając, że istnieje nagłówek, na który możesz patrzeć, aby odróżnić zalogowanych i niezalogowanych użytkowników, to powinno działać. Nie będzie zanieczyszczał pamięci podręcznej, jeśli masz logikę, która zapełni pamięć podręczną wyjściową tylko wtedy, gdy użytkownik nie jest zalogowany. Zalogowani użytkownicy będą zawsze otrzymywać pomyłki w pamięci podręcznej.

+0

VaryByHeader mogłaby zdecydowanie działać, ale będę potrzebował mechanizmu w celu zapewnienia, że ​​nagłówek jest ustawiony. Co sugerujesz? Zaimplementuj moduł HttpModule, który ustawia niestandardowy nagłówek (np. Nagłówki ["custom-header"] = "no-cache", a następnie zmieniają się w zależności od tego: –

+0

Może nie w pełni to przemyślałem. Miałem nadzieję, że będą różne nagłówki pochodzące z przeglądarki (np. plik cookie auth), który pozwoliłby na rozróżnienie tych dwóch przypadków: –

+0

To dobra sugestia, ale wszystko, co mam, to autentyczny podpis uwierzytelniania formularzy lub podobne uwierzytelnianie oparte na plikach cookie, jednak ponieważ istnieją różne rodzaje autoryzacji poziomy, z których wszystkie są rozwiązywane z tego samego mechanizmu uwierzytelniania (np. cookie), mógłbym ustawić różne pliki cookie w zależności od poziomu autoryzacji.Myślę, że brzmi to zawiłe i lubię działać wbrew ramom –