为什么我不能在ASP.NET MVC 2中使用Response.Cache.SetLastModified(以及什么是"缓存限制层次结构"?)

Dyl*_*tie 1 asp.net-mvc caching last-modified http-headers

试图在动态生成的图像上设置缓存响应头,我得到一个奇怪的错误:

ArgumentOutOfRangeException未被用户代码处理

指定的参数超出了有效值的范围.

参数名称:utcDate

我正在从数据缓存中读取文件的最后写入时间,然后调用

Response.Cache.SetLastModified(lastWriteTime.Value.ToUniversalTime());
Run Code Online (Sandbox Code Playgroud)

{2011-07-25 18:09:56}正如我所期望的那样,最后写入时间的值是......我不知道为什么会出错.

此方法的MSDN文档包含相当神秘的声明(我的重点):

Last-Modified HTTP标头时间标记文档,其DateTime值指示上次修改文档的时间.

如果违反了缓存限制性层次结构,则此方法将失败.

SetLastModified是在.NET Framework 3.5版中引入的.有关更多信息,请参阅.NET Framework版本和依赖项.

什么是缓存限制层次结构?我是否违反了一个?如果没有,为什么最后修改时间被拒绝?

Rob*_*nto 6

ArgumentOutOfRangeException如果你lastWriteTime是将来,SetLastModified将抛出.

这将成功:

var t1 = DateTime.Now;
Response.Cache.SetLastModified(t1);
Run Code Online (Sandbox Code Playgroud)

这将失败:

var t2 = DateTime.Now + new TimeSpan(0, 0, 0, 1);
Response.Cache.SetLastModified(t2);
Run Code Online (Sandbox Code Playgroud)

反编译System.Web说明了这一点:

public void SetLastModified(DateTime date)
{
  this.UtcSetLastModified(DateTimeUtil.ConvertToUniversalTime(date));
}

private void UtcSetLastModified(DateTime utcDate)
{
  utcDate = new DateTime(utcDate.Ticks - utcDate.Ticks % 10000000L);
  if (utcDate > DateTime.UtcNow)
    throw new ArgumentOutOfRangeException("utcDate");
  if (this._isLastModifiedSet && !(utcDate > this._utcLastModified))
    return;
  this.Dirtied();
  this._utcLastModified = utcDate;
  this._isLastModifiedSet = true;
}
Run Code Online (Sandbox Code Playgroud)

您是lastWriteTime在一台服务器上生成,然后在服务器之间存在时间差异的另一台服务器上进行读取?

一些额外的要点:

  • 您还可以看到您不需要ToUniversalTime框架为您执行此操作
  • 看起来第一行UtcSetLastModified降低了精度
  • 我不能告诉你想要一个"缓存限制层次结构"!