2015-09-22 3 views
1

ОК, похоже, нет конца количеству статей, которые поют хвалу выходного кэширования и насколько это ускорит ваш сайт. Я теперь прочитал сотни статей и 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.

ответ

0

Вы устанавливаете VaryByParam? Я забываю детали в данный момент, но я помню, как застревал, прежде чем выяснять, что это обязательно. (в каждый кейс я думаю. (?)) Я думаю, продолжительность также требуется. (я имею в виду директивы на странице .aspx.)

+0

только что посмотрел на [msdn] (https://msdn.microsoft.com/en-us/library/hdxfb6cy%28v=vs.100%29.aspx) - необходим VaryByParam или VaryByControl. – wazz

+0

Да. Я установил как продолжительность, так и Varybyparam. Я пробовал Varybyparam ни с одним, ни с ID. Я начинаю думать о том, как строится страница, о чем я говорю.Было бы неплохо найти способ передать пользовательскую строку, чтобы ее можно было прочитать httpcontext. – user2033791

+0

Также, если я устанавливаю variableByCustom для любого значения, отличного от «user» в «Подробности» или «Домой», он останавливает их от кеширования, и GetVaryByCustomString никогда не вызывается. Если это должно быть произвольное значение, то почему бы это сломать, если я установил его на что-то другое? – user2033791

0

Перечитывая свой вопрос, я увидел проблему: «Я не могу найти рабочих примеров, которые позволяют странице определять строку». Я перечитывал некоторые статьи, и я уверен, что это неправильный подход.

я не проверял все это, но и для бывших, если взять стандартный пример:

<%@ OutputCache Duration="10" VaryByParam="None" VaryByCustom="minorversion" %>

что, кажется, происходит то, что вы просто задать строку для поиска, и это оно.

При поступлении запроса вы проверяете заголовок запроса HTTP - заголовок Vary, который вы установили на странице - и если он существует, вы делаете то, что хотите.

<%@ Application language="C#" %> 
<script runat="server"> 
public override string GetVaryByCustomString(HttpContext context, 
    string arg) 
{ 
    // arg is your custom 'Vary' header. 
    if(arg == "minorversion") 
    { 
     return "Version=" + 
      context.Request.Browser.MinorVersion.ToString(); 
    } 
    return base.GetVaryByCustomString(context, arg); 
} 
</script> 

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

... на второй мысли, я думаю, вы создать заголовок на странице, и возврата товара значение из global.asax. где?? я думаю, что он отправлен в систему кэширования , которая решает, следует ли отправлять новую или кэшированную страницу. в приведенном выше примере малая версия браузера проверяется и устанавливается, и поскольку имеется доступная в кэше версия (после первой загрузки), она отправляет ее до 10 секунд.

Документы для VaryByCustom находятся в разделе «кэширование разных версий страницы», так что это и делается. если отображается кто-то с другим браузером, проверяется версия браузера - тогда система кэширования проверяет, доступна ли версия страницы для этой версии браузера. если нет, создайте новую страницу; если да, отправьте кешированную версию.

+0

Спасибо за информацию, но то, что я ищу, это способ установить значение, возвращаемое GetVaryByCustomString из самой страницы. Таким образом, некоторый способ загрузить переменную из httpContext, чтобы она стала строковым значением кеша. Итак, что-то вроде HttpContext.Request.Items.Add («SearchString», «Color = Red») – user2033791

+0

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

+0

просто чтобы проверить, знаете ли вы, что вы можете сделать простое кэширование с помощью: 'Cache [" SearchString "] =" Red ";' и вернуть его с помощью 'string currColor = Cache [" SearchString "];'? – wazz

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