5

我正在尝试在我的 ASP.NET MVC 网站中使用 OutputCaching。问题是,当我尝试更改我的查询字符串参数的值时,它会返回请求的第一个项目的数据!

这是我的代码(更改了参数名称)...

[ApiAuthorize]
[HandleErrorAsJson]
public class SearchController : Controller
{
    [AcceptVerbs(HttpVerbs.Get)]
    [OutputCache(Duration = 60, VaryByParam = "*")]
    public ActionResult ScoreCard(string foo, byte? bar, byte? pewpew)
    {
    ..
    }
}
  • 注意 1:ApiAuthorize - 检查名为“Key”的查询字符串参数并检查内存字典以查看它是否存在的自定义属性。
  • 注意 2:HandleErrorAsJson - 如果抛出异常,则以 json 格式返回错误消息的自定义属性。

这是我对此操作进行的两个示例调用:-

因此,第一次调用 (foo = hello world, Pew Pew) 的数据返回 200 OK。然后第二个 api 调用返回 200 OK,但包含上一次调用的数据。

另外,我没有使用任何代理服务器。如果我注释掉 OutputCache 属性,一切都很好。

我也尝试过以下(每次我需要缓存时手动列出).....

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

没运气 :(

请注意我需要如何确保将 API 'Key' 参数作为缓存唯一键的一部分。我不希望人们搜索相同的东西,但是如果第二个人没有正确的密钥,他们不应该得到缓存的结果,而是一条错误消息(从技术上讲,它是 401 Not Authorized,但是无论如何)...

想法?

4

2 回答 2

4

VaryByParam 中的参数列表应该以分号分隔,而不是逗号分隔。试试看。也就是说, * 应该有效。

于 2009-09-17T13:37:11.470 回答
0

我使用一个过滤器进行输出缓存,它将为调试提供编程控制,并在需要时进行设置。随意使用它,看看在这里设置它是否会产生我认为可能的不同(还要确保清除任何以前的缓存)

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 作为属性公开,可以提供但听起来您知道该怎么做。

于 2009-09-17T07:20:23.007 回答