2011-01-29 2 views
5

У меня вопрос о том, как программно инструктировать ASP.NET, чтобы пропустить разрешение запроса из выходного кэша.Условное кэширование вывода в ASP.NET

Представьте, что у вас есть кеш-страница страницы (например, http://domain/page.aspx) с помощью применения параметров политики кэширования от CMS до HttpResponse во время выполнения. В на основе запроса в зависимости от того, является ли текущий пользователь аутентифицирован + членом набора известных групп (или соответствует бизнес-логике), я хотел бы указать ASP.NET на skip, разрешая запрос с вывода кэш.

Сценарий состоит в том, что в системе одновременно используются два разных пользователя (или более). Пользователь A аутентифицируется + член набора известных групп, а пользователь B является анонимным. Независимо от того, какая страница выводится в кеш, я хочу, чтобы аутентифицированный пользователь просматривал все страницы, как если бы кеширование вывода не было включено; в то же время я хотел бы, чтобы ASP.NET продолжал обслуживать выходные кешированные страницы анонимным пользователям (или пользователям, которые не соответствуют бизнес-логике).

Типичное предложение - использовать VaryByHeader, VaryByParam и т. Д. И загрязнять выходной кеш - не очень хорошо, но, копая в модуле выходного кэша с использованием Reflector, я заметил, что модуль кэша вывода пропускает текущий запрос в случае, если пара известных заголовков «кеш-контроль». Что касается заголовков, они отправляются из браузера, если пользователь заставляет новую копию визуализироваться, нажав F5 или ENTER в адресной строке.

Итак, я просто устанавливаю заголовок «cache-control» в «no-cache» в настраиваемом модуле http в событии, которое происходит до события ResolveRequestCache, к которому подписывается выходной кеш. Как это:

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

Все это хорошо и денди, однако, если HttpCachePolicy.SetValidUntilExpires политика (истина) кэш установлен, ASP.NET игнорирует заголовок запроса ранее установленного и обслуживает запрос из кэша вывода.

В качестве альтернативы, я думаю, я мог бы написать дополнительный код в событии после обработки в том же http-модуле, чтобы гарантировать, что HttpCachePolicy.SetValidUntilExpires (false) вызывается, в случае, если кэширование вывода настроено, но я думаю, что это было бы более чистым решением, позволяющим на самом деле дать указание ASP.NET просто пропустить разрешение запроса из выходного кэша. Я могу представить себе много важных решений этого вопроса, но я за правильной.

Для справки, я пытался большинство, если не все соответствующие методы класса HttpCachePolicy т.д .:

HttpResponse.Cache.SetNoServerCaching()). 

ответ

3

В приложение добавлено приложение HttpCacheValidateHandler, в котором вы можете выполнить любую логику которую вы хотите. Он будет выполнен во время события ResolveRequestCache, которое запускается после выполнения проверки подлинности и авторизации. Ключ должен вернуть HttpValidationStatus.IgnoreThisRequest в том случае, если вы хотите обойти кеш.

Смотрите этот пример HttpModule для справки:

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

Оливер, никогда не поздно и спасибо для ответа, который я сейчас реализовал. Мне интересно, как я мог пропустить метод ** AddValidationCallback **. работая с каркасом, и это то, что я пропустил с предыдущей реализацией. –

0

я не уверен, есть ли поддерживаемый способ сделать это после того, как что-то кэшируется.

Но почему вам не нравится опция VaryByHeader? Предполагая, что есть заголовок, на который вы можете посмотреть, чтобы различать входные и не входящие в систему пользователи, которые должны работать. Это не будет загрязнять кеш, если у вас есть логика, чтобы заполнять только выходной кеш, если пользователь не вошел в систему. Записанные пользователи всегда будут пропускать кеш.

+0

VaryByHeader определенно может работать, но я должен был бы механизм, гарантирующий, что заголовок установлен. Что вы предлагаете? Реализуйте HttpModule, который устанавливает пользовательский заголовок (т.е. Заголовки ["custom-header"] = "no-cache", а затем меняются? –

+0

Возможно, я не полностью обдумал это. Я надеялся, что будут разные заголовки исходя из браузера (например, auth cookie), что позволило бы дифференцировать два случая. –

+0

Это хорошее предложение, но все, что у меня есть, - это фактически подпись аутентификации форм или аналогичная аутентификация на основе файлов cookie. Однако, поскольку существуют различные виды авторизации уровни, из которых все разрешены из одного и того же механизма аутентификации (т. е. cookie), я мог бы прибегнуть к настройке разных файлов cookie в зависимости от уровня авторизации. Я думаю, что это звучит запутанно и как работа с каркасом. –

 Смежные вопросы

  • Нет связанных вопросов^_^