Кеширование не работает правильно на моем сайте ASP.NET MVC? - PullRequest
5 голосов
/ 17 сентября 2009

Я пытаюсь использовать 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 не авторизован, но в любом случае) ...

Мысли

Ответы [ 2 ]

4 голосов
/ 17 сентября 2009

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

0 голосов
/ 17 сентября 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 отображался как свойство, но могло показаться, что вы знаете, что делать.

...