Кэширование частичного вывода страницы в Asp.Net MVC 3 не учитывает настройки конфигурации - PullRequest
7 голосов
/ 25 января 2011

У меня есть простое частичное представление, которое я отображаю в моем основном виде:

 @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, а если нет, то почему?

Ответы [ 2 ]

5 голосов
/ 26 января 2011

Итак, я взял минуту и ​​посмотрел на источник MVC 3. Первое, что пришло мне в голову, было то, что эта функция казалась немного хакерской. Главным образом потому, что они повторно используют атрибут, который работает в одной ситуации, соблюдая все свойства и параметры конфигурации, а затем в сценарии дочернего действия просто игнорируя все эти параметры и позволяя только VaryByParam и Duration .

Как понять, что поддерживается, мне не под силу. Потому что исключение, которое они хотят сгенерировать и которое говорит Неподдерживаемая настройка , никогда не будет выброшено, если вы не указали длительность и значение 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, это должно прояснить или, по крайней мере, выдать правильное исключение.

Короче говоря, частичное кэширование вывода работает, НО не так, как вы этого хотели бы. Я поработаю над исправлением кода и выполнением некоторых настроек, таких как enabled .

Обновление: Я исправил текущую реализацию, чтобы она работала, по крайней мере, в моей ситуации с соблюдением флага включения и разрешением профилей кэша из файла web.config. Подробно в моем блоге.

0 голосов
/ 01 февраля 2011

Вот более простой подход, если:

  • Ваша основная цель - иметь возможность отключить кэш во время отладки и включить его во время развертывания
  • У вас нет сложных политик кэширования
  • У вас нет сложной системы развертывания, которая использует синтаксис кэширования Web.config
  • Идеально, если вы используете Веб-преобразования XDT уже

Все, что я сделал, - это создал новый атрибут 'DonutCache'.

[DonutCache]
public ActionResult HomePageBody(string viewName)
{
    var model = new FG2HomeModel();

    return View(viewName, model);
}

К сожалению, [Attribute] можно инициализировать только константой,поэтому вам нужно инициализировать атрибут в его конструкторе. Примечание : Это не мешает вам установить 'varByParam' в объявлении [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, которое вы уже используете, чтобы изменить это значение

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...