Программно управлять кэшированием вывода - отключить или включить кеш в соответствии с значением параметра
У нас есть довольно стандартный сценарий электронной коммерции с выгружаемыми списками продуктов в категориях. К лучшему или худшему, около 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.
Ответы
Ответ 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);
}
Ответ 3
Я считаю, что лучший способ сделать это - использовать HttpCachePolicy.AddValidationCallback
См. http://www.hanselman.com/blog/AdvancedASPNETCachingAndAddValidationCallBack.aspx - Полный пример, который отвечает именно на этот вопрос.
Ответ 4
Вы все равно можете использовать директиву outputcache, и, на мой взгляд, вместо того, чтобы засорять код вашей страницы кучей кеширующих гаек и болтов, вам лучше пойти с многоразовым решением, основанным на обработке этого в Global.asax вы обычно можете использовать любой сценарий VaryByCustom.
Итак, например, если вы используете подкастинг с ретранслятором, вы можете просто в своем сценарии поиска исключить любую обратную передачу на определенной странице из кеша. Здесь - пример кода, который делает именно это. Подход просто требует использования объекта HttpContext для доступа к Response.Cache.SetNoServerCaching() после захвата любых критериев, для которых вы хотите избежать кеширования. Надеюсь, это поможет.
Ответ 5
Я думаю, вы должны использовать директиву OutputCache с свойством VaryByParam, установленным в список разделенных запятыми строк, используемых для изменять выходной кеш.
Если вы не хотите просто кэшировать только, когда Page == 1?