Почему я не могу Response.Cache.SetLastModified в ASP.NET MVC 2 (и что такое «иерархия ограничений кэширования»?) - PullRequest
1 голос
/ 25 июля 2011

При попытке установить заголовки ответа кеша для динамически генерируемого изображения, я получаю странную ошибку:

ArgumentOutOfRangeException не обрабатывается кодом пользователя

Указанный аргумент был издиапазон допустимых значений.

Имя параметра: utcDate

Я читаю время последней записи файла из кэша данных, а затем вызываю

Response.Cache.SetLastModified(lastWriteTime.Value.ToUniversalTime());

Значение времени последней записи {2011-07-25 18:09:56}, как я и ожидал ... Я понятия не имею, почему это не так.

Документация MSDN для этого метода содержит довольнозагадочное утверждение (мой акцент):

Время последнего изменения заголовка HTTP помечает документ значением DateTime, указывающим, когда документ был последний раз изменен.

Этот метод будетошибка, если нарушена иерархия ограничения кэширования.

SetLastModified введен в .NET Framework версии 3.5.Для получения дополнительной информации см. Версии и зависимости .NET Framework.

Что такое иерархия ограничений кэширования?Я нарушаю один?Если нет, то почему время последнего изменения было отклонено?

1 Ответ

6 голосов
/ 25 июля 2011

SetLastModified выбросит ArgumentOutOfRangeException, если ваш lastWriteTime находится в будущем.

Это удастся:

var t1 = DateTime.Now;
Response.Cache.SetLastModified(t1);

Это не удастся:

var t2 = DateTime.Now + new TimeSpan(0, 0, 0, 1);
Response.Cache.SetLastModified(t2);

Декомпиляция 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;
}

Вы генерируете lastWriteTime на одном сервере, а затем читаете на другом, где между серверами есть расхождение во времени?

Некоторые дополнительные очки:

  • Вы также можете видеть, что вам не нужно ToUniversalTime, так как фреймворк делает это для вас
  • Похоже, что первая строка в UtcSetLastModified снижает точность
  • Не могу сказать, что вы хотите, чтобы "иерархия ограничений кэширования" была!
...