Asp.Net MVC 3 Частичное кэширование вывода страницы Не соблюдение настроек конфигурации
У меня есть простой частичный вид, который я просматриваю в своем основном представлении с помощью:
@Html.Action("All", "Template")
На моем контроллере у меня есть это:
[OutputCache(CacheProfile = "Templates")]
public ActionResult All()
{
return Content("This stinks.");
}
И в моей конфигурации это:
<caching>
<outputCacheSettings>
<outputCacheProfiles>
<clear/>
<add name="Templates" duration="3600" varyByParam="none"/>
</outputCacheProfiles>
</outputCacheSettings>
<outputCache enableOutputCache="false" enableFragmentCache="false" />
</caching>
Это приведет к сбою во время выполнения с исключением:
Ошибка выполнения дочернего запроса для обработчика 'System.Web.Mvc.HttpHandlerUtil + ServerExecuteHttpHandlerAsyncWrapper
И внутреннее исключение:
Продолжительность должна быть положительным числом
Теперь, очевидно, он не подбирает мои настройки web.config, потому что если я его сменил на:
[OutputCache(Duration = 3600)]
Он будет работать, но также заметьте в моем web.config, я отключил enableOutputCache и enableFragmentCache, но не соблюдает эти настройки.
Любопытно, что в нормальном режиме эти настройки работают нормально, так что же это о частичных представлениях, которые нарушают это? Я что-то упускаю? Гу говорит, что это должно работать нормально...
Короче говоря, он должен соблюдать настройки кэширования в web.config, а если нет, то почему?
Ответы
Ответ 1
Итак, я потратил минуту и посмотрел на источник MVC 3. Первое, что пришло ко мне, это было немного взломанным. В основном потому, что они повторно используют атрибут, который работает в одной ситуации с соблюдением всех свойств и настроек конфигурации, а затем в сценарии действий с детьми просто игнорирует все эти настройки и разрешает только VaryByParam и Длительность.
Как можно было бы понять, что поддерживается, вне меня. Поскольку исключение, которое они хотят выбросить, которое говорит, что Неподдерживаемая настройка никогда не будет выбрано, если вы не указали продолжительность и значение VaryByParam
Вот основная часть кода, которая пахнет:
if (Duration <= 0) {
throw new InvalidOperationException(MvcResources.OutputCacheAttribute_InvalidDuration);
}
if (String.IsNullOrWhiteSpace(VaryByParam)) {
throw new InvalidOperationException(MvcResources.OutputCacheAttribute_InvalidVaryByParam);
}
if (!String.IsNullOrWhiteSpace(CacheProfile) ||
!String.IsNullOrWhiteSpace(SqlDependency) ||
!String.IsNullOrWhiteSpace(VaryByContentEncoding) ||
!String.IsNullOrWhiteSpace(VaryByHeader) ||
_locationWasSet || _noStoreWasSet) {
throw new InvalidOperationException(MvcResources.OutputCacheAttribute_ChildAction_UnsupportedSetting);
}
Я не уверен, почему это не вызвано в документации, но даже если бы это было api, или, по крайней мере, выбросить правильное исключение.
Короче говоря, работает частичное кэширование вывода, BUTT не похоже, что вы тоже захотите. Я буду работать над исправлением кода и соблюдением некоторых параметров, таких как включен.
Update:
Я исправил текущую реализацию, по крайней мере, для своей ситуации с учетом включенного флага и разрешения профилей кэша из web.config. Подробно в моем сообщении в блоге.
Ответ 2
Здесь более простой подход, если:
- Основная цель состоит в том, чтобы отключить кеш при отладке, а включить его во время развертывания
- У вас нет сложных политик кэширования.
- У вас нет сложной системы развертывания, которая опирается на синтаксис кэширования Web.config
- Идеально, если вы уже используете веб-преобразования XDT
Все, что я сделал, был создан новый атрибут "DonutCache".
[DonutCache]
public ActionResult HomePageBody(string viewName)
{
var model = new FG2HomeModel();
return View(viewName, model);
}
К сожалению, вы можете инициализировать только [Attribute]
с константой, поэтому вам нужно инициализировать атрибут в его конструкторе. Примечание. Это не мешает вам устанавливать параметр variableByParam в объявлении [DonutCache].
class DonutCacheAttribute : OutputCacheAttribute
{
public DonutCacheAttribute()
{
Duration = Config.DonutCachingDuration;
}
}
Здесь я просто инициализирую атрибут из моего web.config с помощью статического свойства:
<appSettings>
<add key="DonutCachingDuration" value="5"/>
</appSettings>
public static class Config {
public static int DonutCachingDuration
{
get
{
return int.Parse(ConfigurationManager.AppSettings["DonutCachingDuration"]);
}
}
}
Затем, конечно, вы можете использовать веб-преобразование XDT, которое вы уже используете, чтобы изменить это значение