Кэширование условного вывода в ASP.NET - PullRequest
5 голосов
/ 29 января 2011

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

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

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

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

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

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

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

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

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

HttpResponse.Cache.SetNoServerCaching()).

Ответы [ 2 ]

3 голосов
/ 09 октября 2012

Вы можете добавить 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 голосов
/ 31 января 2011

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

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

...