ОК, похоже, нет конца количеству статей, которые поют хвалу выходного кэширования и насколько это ускорит ваш сайт. Я теперь прочитал сотни статей и Q & Как по теме, но я все еще не могу заставить ее работать. (Я думаю, что выходное кэширование может украсть мою душу)Выходное кэширование, VaryByParam/VaryByCustom
Мои требования довольно просты, у меня есть 3 страницы, которые я хотел бы кэшировать на основе параметров: Главная, Результаты и Детали. У меня также есть небольшая область страницы, которая должна быть изменена пользователем. Мне также нужно кэшировать в центральный репозиторий, и я выбрал redis для хранения моих данных. Я должен также упомянуть, что это все еще старое приложение для веб-форм.
Мой первоначальный подход состоял в том, чтобы попытаться предоставить свою собственную строку, используя опцию «VaryByCustom». На странице Microsoft, кажется, делает это выглядит просто:
https://msdn.microsoft.com/en-us/library/5ecf4420.aspx
Это требует размещения перекрытый метод «GetVaryByCustomString» в файле global.asax. Проблема заключается в том, что большинство примеров показывают использование переменных из HttpContext, которые всегда доступны (браузер, версия браузера и т. Д.), И хотя Microsoft и другие, похоже, предлагают это как предпочтительный метод «кэша по пользовательской строке», который я не могу найти любые рабочие примеры, которые позволяют странице определять строку. Я видел несколько примеров людей, использующих сеанс и утверждающих, что он работает (сеанс для меня равен null) и context.user (некоторые говорят, что пользователь имеет значение NULL), но я не вижу практического способа доставки строки, кроме как используя Response.Cache.SetVaryByCustom ("my_custom_string"). После дня борьбы с реализацией в основном проекте я решил построить изолированный проект для тестирования/доказательства концепции. В этом проекте я смог получить свою пользовательскую строку, пока я передал ее как строку в SetVaryByCustom. Проблема в том, что это не соответствует никаким примерам, которые я видел. В примерах показано, что «SomeKey» с «SomeValue» возвращается GetVaryByCustomString. Для меня работала «SomeValue» с «SomeValue». Вот мой код:
public override string GetVaryByCustomString(HttpContext context, string arg)
{
if (arg != null)
{
return arg;
}
return base.GetVaryByCustomString(context, arg);
}
Это работало в первый раз на странице, после установки значения раскрывающегося списка, который создал постбэк, но никогда после этого. Таким образом, «OnselectedItemChanged» выстрелил один раз и создал новый набор записей кэша на основе выбора, но он больше не запускался. Я попытался изменить практически каждый параметр кеша, который мог бы сделать, чтобы он работал, но независимо от того, какую серию настроек я пытался (задал кеш декларативно, установил кеширование в коде, пробовал различные комбинации VaryByParams, добавляя местоположение и т. Д.). Я никогда не был успешным.
После того, как вы проработали 2 дня, чтобы заставить это работать, я решил, что пришло время для другого подхода. Я вернулся к более традиционному/общепринятому подходу. я создал 3 профилей кэша в моем web.config:
<caching>
<cache disableExpiration="false" />
<outputCache defaultProvider="RedisOutputCacheProvider" enableOutputCache="true" enableFragmentCache="true" sendCacheControlHeader="true">
<providers>
<add name="RedisOutputCacheProvider"
type="LAC.OutputCacheProvider, LAC"
connectionString="192.168.XX.XX:6379,connectTimeout=10000"
dbNumber="5"
keyPrefix="LAC:OutputCache:" />
</providers>
</outputCache>
<outputCacheSettings>
<outputCacheProfiles>
<add name="Home" varyByParam="*" varyByCustom="user" duration="86400"/>
<add name="Results" varyByParam="*" varyByCustom="user" duration="7200" />
<add name="Details" varyByParam="*" varyByCustom="user" duration="7200"/>
</outputCacheProfiles>
</outputCacheSettings>
</caching>
Таким образом, каждая страница имеет обычай меняться в зависимости от строки пользователя, который должен помочь мне кэшировать новую страницу для аутентифицированного пользователя против анонимного одного. Затем я добавил GetVaryByCustomString, который выглядит как:
public override string GetVaryByCustomString(HttpContext context, string arg)
{
switch (arg)
{
case "user":
var identity = context.User.Identity.Name != "" ? context.User.Identity.Name : "Anonymous";
return string.Format("IsAuthenticated={0},Identity={1}", context.Request.IsAuthenticated, identity);
}
return string.Empty;
}
Я так близко, как я когда-либо к тому, эту работу, но это еще не 100%. Домашняя страница работает нормально, подробная страница работает отлично, но страница результатов никогда не кэшируется. На странице результатов есть фильтр, содержащий 12 разных выпадающих списков. Поэтому он должен хранить версию страницы на основе выбора. Я добавил отметку времени на все мои страницы, чтобы увидеть, была ли страница кешированием. Время на странице результатов изменяется каждый раз, когда я нажимаю control-F5, что неверно на других 2 страницах. Никакие записи кэша никогда не создаются, и GetVaryByCustomString никогда не вызывается.Я трижды проверил код на какой-то параметр «Отключить кеширование», но насколько я могу судить, на странице нет кода, который отключает кеш. Мой файл global.asax наследуется от правильного класса, мой пользовательский поставщик ouputcache, кажется, добавляет правильные записи для двух страниц, которые работают. Конечно, теперь с VaryByParam = "*" ключ может быть до тех пор, как контент благодаря viewstate (который должен быть оставлен) BLECH!
Итак, у меня есть кеширование, установленное на трех страницах, похожих на одно, и одно не работает. Я понятия не имею, где искать дальше. Я надеюсь, что кто-то, как @kevinmontrose, у которого действительно есть ручка на такого рода материалах, пожалеет меня и даст мне толчок в направлении, которое приведет меня к решению.
ОБНОВЛЕНИЕ: Я открыл дело с Microsoft.
только что посмотрел на [msdn] (https://msdn.microsoft.com/en-us/library/hdxfb6cy%28v=vs.100%29.aspx) - необходим VaryByParam или VaryByControl. – wazz
Да. Я установил как продолжительность, так и Varybyparam. Я пробовал Varybyparam ни с одним, ни с ID. Я начинаю думать о том, как строится страница, о чем я говорю.Было бы неплохо найти способ передать пользовательскую строку, чтобы ее можно было прочитать httpcontext. – user2033791
Также, если я устанавливаю variableByCustom для любого значения, отличного от «user» в «Подробности» или «Домой», он останавливает их от кеширования, и GetVaryByCustomString никогда не вызывается. Если это должно быть произвольное значение, то почему бы это сломать, если я установил его на что-то другое? – user2033791