Подтвердить что ты не робот

Программно управлять кэшированием вывода - отключить или включить кеш в соответствии с значением параметра

У нас есть довольно стандартный сценарий электронной коммерции с выгружаемыми списками продуктов в категориях. К лучшему или худшему, около 80% посетителей никогда не перемещаются мимо первой страницы, в зависимости от категории может быть еще 5-10 страниц результатов, которые просматриваются гораздо реже. (Да, мы оптимизируем то, что появляется на первой странице и имеют хороший поиск, - но это другое обсуждение)

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

Я знаю, что мог бы сделать что-то подобное, используя кэширование объектов для хранения данных, о которых идет речь, но возможно ли это с помощью кэширования вывода, возможно, с помощью объекта response.Cache?

Где в жизненном цикле страницы это можно сделать? Pre-визуализация?

Намного проще, URL-адрес похож на "/ProductList? Category = something & Page = 1" И я бы хотел, чтобы логика была похожа на (псевдокод):

If paramater "Page" equals 1
   Use output caching: vary by param = "categoryName; page"
else
   Don't use caching at all, just render the page from scratch.

Мы используем ASP.NET 2.0 на IIS 6/win2003.

4b9b3361

Ответ 1

Вместо использования директивы OutputCache вы можете сделать то же самое программно, как показано ниже:

if (yourArbitraryCondition) {
  OutputCacheParameters outputCacheSettings = new OutputCacheParameters();
  outputCacheSettings.Duration = 60;
  InitOutputCache(outputCacheSettings);
}

Выполнение этого с OnInit должно работать нормально. И, очевидно, вы можете настроить поведение кэширования, установив различные свойства на OutputCacheParameter, который имеет все те же ручки, что и директива (фактически, это то, что мы генерируем при использовании директивы).

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

UPDATE:

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

HttpCachePolicy cache = Response.Cache;
cache.SetCacheability(HttpCacheability.Public);
cache.SetExpires(Context.Timestamp.AddSeconds(60));
cache.VaryByParams["categoryName"] = true;

В принципе, это другой способ сделать то же самое, без использования какого-либо API, помеченного как "не следует вызывать". В конце концов, любой из них будет работать, так что сделайте выбор.

Ответ 2

edit: Мне нравится, что Дэвид Эббо отвечает намного лучше, чем мой собственный.


Вы можете использовать

<%@ OutputCache Duration="60"  VaryByParam="none" VaryByCustom="pageOne" %>

и реализовать его таким образом, который возвращает фиксированный ключ для первой страницы и случайный ключ для всех других страниц. Вы можете (и должны) позволить очистить механизм позаботиться о памяти, но вы можете использовать HttpResponse.RemoveOutputCacheItem для удаления элементов кэша, если вам нужно.

public override string GetVaryByCustomString(HttpContext ctx, string custom)
{
    if(custom == "pageOne")
    {
        if(ctx.Request["page"] == "1")
        {
            return "1";
        }

        HttpResponse.RemoveOutputCacheItem("/Default.aspx");
        return Guid.NewGuid().ToString();
    }
    return base.GetVaryByCustomString(ctx, custom);
}

Ответ 4

Вы все равно можете использовать директиву outputcache, и, на мой взгляд, вместо того, чтобы засорять код вашей страницы кучей кеширующих гаек и болтов, вам лучше пойти с многоразовым решением, основанным на обработке этого в Global.asax вы обычно можете использовать любой сценарий VaryByCustom.

Итак, например, если вы используете подкастинг с ретранслятором, вы можете просто в своем сценарии поиска исключить любую обратную передачу на определенной странице из кеша. Здесь - пример кода, который делает именно это. Подход просто требует использования объекта HttpContext для доступа к Response.Cache.SetNoServerCaching() после захвата любых критериев, для которых вы хотите избежать кеширования. Надеюсь, это поможет.

Ответ 5

Я думаю, вы должны использовать директиву OutputCache с свойством VaryByParam, установленным в список разделенных запятыми строк, используемых для изменять выходной кеш.

Если вы не хотите просто кэшировать только, когда Page == 1?