使用OutputCacheAttribute时忽略SetLastModified

时间:2011-02-09 13:57:30

标签: asp.net-mvc asp.net-mvc-3 http-caching output-caching

我有一个ASP.NET MVC方法(.NET 4.0上的v3.0)设置如下:

[OutputCache(Duration = 31536000, Location = OutputCacheLocation.Any)]
public virtual ActionResult Item()
{
    this.Response.Cache.SetLastModified(new DateTime(2011, 01, 01));
    return this.Content("hello world", "text/plain");
}

我希望这会将Last-Modified标头设置为Mon, 07 Feb 2011 00:00:00 GMT,但是它实际上会作为输出首先缓存在输出缓存中的日期返回(即自IIS重置以来第一次调用该方法。

如果我注释掉[OutputCache]属性以便不进行输出缓存,那么Last-Modified标头会按预期返回,因此看起来输出缓存基础结构中的某些东西选择忽略我的指定的值。

知道为什么会这样做吗?有没有办法让它使用我的指定值作为Last-Modified日期?

2 个答案:

答案 0 :(得分:2)

好吧,我从来没有解决过这种情况的原因,但它看起来像是[OutputCache]属性使用的ASP.NET页面缓存基础结构中的某个地方的错误。

我最终编写了一个具有相同公共接口的自定义[HttpCache]属性,但它直接调用Response.Cache对象上的相应缓存方法,而不是委托给ASP.NET页面缓存基础结构。

工作正常。遗憾的是内置属性没有。

答案 1 :(得分:0)

在Controller的OnResultExecuting事件期间,[OutputCache]创建System.Web.UI.Page的实例以处理属性中指定的缓存属性。他们这样做是因为Page已经有逻辑将OutputCacheParameters转换为实际的http缓存指令。

https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/OutputCacheAttribute.cs

    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        if (filterContext == null)
        {
            throw new ArgumentNullException("filterContext");
        }

        if (!filterContext.IsChildAction)
        {
            // we need to call ProcessRequest() since there's no other way to set the Page.Response intrinsic
            using (OutputCachedPage page = new OutputCachedPage(_cacheSettings))
            {
                page.ProcessRequest(HttpContext.Current);
            }
        }
    }

OutputCacheAttribute基本上将原始处理程序(控制器)的输出复制到为配置缓存而创建的页面。

这里的缺点是添加到原始HttpResponse的标头不会被复制到新的处理程序(页面)。这意味着无法在控制器中的Response上设置标头。实际处理请求的页面会忽略这些标题。