Кэширование не работает прямо на моем веб-сайте ASP.NET MVC?

я пытаюсь использовать OutputCaching на своем веб-сайте ASP.NET MVC. Проблема в том, что когда я пытаюсь изменить значение одного из моих параметров строки запроса, он возвращает данные для первого запрошенного элемента!

Вот мой код (с измененными именами параметров)...

[ApiAuthorize]
[HandleErrorAsJson]
public class SearchController : Controller
{
    [AcceptVerbs(HttpVerbs.Get)]
    [OutputCache(Duration = 60, VaryByParam = "*")]
    public ActionResult ScoreCard(string foo, byte? bar, byte? pewpew)
    {
    ..
    }
}
  • ПРИМЕЧАНИЕ 1: ApiAuthorize — настраиваемый атрибут, который проверяет параметр строки запроса под названием «Ключ» и проверяет словарь в памяти, чтобы увидеть, существует ли он.
  • ПРИМЕЧАНИЕ 2: HandleErrorAsJson — настраиваемый атрибут, который возвращает сообщение об ошибке в формате json, если было создано исключение.

и вот два примера вызовов, которые я делаю для этого действия: -

поэтому данные первого вызова (foo = hello world, Pew Pew) возвращаются как 200 OK. Затем второй вызов API возвращает 200 OK, но с данными предыдущего вызова.

Кроме того, я не использую прокси-сервер. Если я закомментирую атрибут OutputCache, все будет хорошо.

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

[OutputCache(Duration = 60, VaryByParam = "foo,key,bar,pewpew")]

Не повезло :(

Обратите внимание, как мне нужно убедиться, что я включил параметр «Ключ» API как часть уникального ключа кэша. Я не хочу, чтобы люди искали одно и то же, но если у второго человека нет правильного ключа, он должен получить не кешированный результат, а сообщение об ошибке (технически это 401 Not Authorized, но в любом случае)...

Мысли?


person Pure.Krome    schedule 17.09.2009    source источник


Ответы (2)


Список параметров в VaryByParam должен быть разделен точкой с запятой, а не запятой. Попробуйте. Тем не менее, * должен был работать.

person Craig Stuntz    schedule 17.09.2009
comment
+1 еще прямо сосредоточено на рассматриваемом вопросе, хорошо. хотя я не думаю, что это единственная проблема, которую он имеет здесь. ответил на ваш комментарий ниже тоже. - person dove; 17.09.2009

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

public class CacheFilterAttribute : ActionFilterAttribute
    {
        private const int Second = 1;
        private const int Minute = 60 * Second;
        private const int Hour = 60 * Minute;
        public const int SecondsInDay = Hour * 24;


        /// <summary>
        /// Gets or sets the cache duration in seconds. The default is 10 seconds.
        /// </summary>
        /// <value>The cache duration in seconds.</value>
        public int Duration
        {
            get;
            set;
        }

        public int DurationInDays
        {
            get { return Duration / SecondsInDay; }
            set { Duration = value * SecondsInDay; }
        }

        public CacheFilterAttribute()
        {
            Duration = 10;
        }

        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            if (Duration <= 0) return;

            HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache;
            TimeSpan cacheDuration = TimeSpan.FromSeconds(Duration);

            cache.SetCacheability(HttpCacheability.Public);
            cache.SetExpires(DateTime.Now.Add(cacheDuration));
            cache.SetMaxAge(cacheDuration);
            cache.AppendCacheExtension("must-revalidate, proxy-revalidate");
        }
    }

Пока я использую это только для очень статичной части сайта, так что сделайте такой вызов

[CacheFilter(DurationInDays = 1)]

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

person dove    schedule 17.09.2009
comment
Ради интереса, почему вы в конечном итоге создали свой собственный атрибут здесь? - person Pure.Krome; 17.09.2009
comment
Я подал заявку на пару просмотров и сделаю еще. Я не был на 100% точным настройкам, которые вы видите выше, поэтому с этим я легко мог настроить и знал, что он применяется везде. Я до сих пор не решил, добавлять ли больше заголовков при настройке кеша. Конечно, если я сочту это плохой идеей, я могу сделать это чистым расширением атрибута OutputCache и ничего не потерять. Короче говоря, было что выиграть с четким путем к безопасности, если возникнет какой-либо риск. - person dove; 17.09.2009
comment
В том, что он здесь сделал, нет ничего плохого, но это не отвечает на ваш вопрос. Созданный им фильтр влияет на кэширование браузера, а не на кэширование сервера. Это законно, и я не знаю ничего, встроенного в ASP.NET MVC, которое бы это делало. Это также косвенно указывает на то, что здесь задействованы два разных кеша: один в браузере и один на сервере. Мне кажется, что ваш вопрос связан с кешем сервера, хотя было бы неплохо дважды проверить это с помощью Firebug или Fiddler. - person Craig Stuntz; 17.09.2009
comment
@Craig спасибо, что указали на это, я предполагал, что HttpCacheability.Public включает сервер, но вы правы, это не так. И глядя не возможно иметь полный выбор. То есть вы можете установить HttpCacheability.ServerAndPrivate, но это исключит прокси-серверы (ISP), которые мне определенно нужны. Однако вышеприведенное также кэширует на сервере благодаря AppendCacheExtension(must-revalidate, proxy-revalidate); Я подтвердил это во время отладки, когда добавлял это, так что это кеш сервера, хотя и не полностью выраженный и потенциально с проблемами. - person dove; 17.09.2009
comment
AppendCacheExtension делает одну вещь: добавляет текст в заголовок ответа HTTP. См. msdn.microsoft.com/en-us/library. / То, что он добавляет текст к ответу, а не к запросу, говорит вам, на что он влияет. - person Craig Stuntz; 17.09.2009