Фильтр ответов ASP.NET MVC + атрибут OutputCache

Я не уверен, относится ли это к конкретному ASP.NET MVC или к ASP.NET в целом, но вот что происходит. У меня есть фильтр действий, который удаляет пробелы с помощью фильтра ответа:

public class StripWhitespaceAttribute : ActionFilterAttribute
{
    public StripWhitespaceAttribute ()
    {

    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        base.OnResultExecuted(filterContext);

        filterContext.HttpContext.Response.Filter = new WhitespaceFilter(filterContext.HttpContext.Response.Filter);
    }
}

При использовании вместе с атрибутом OutputCache мои вызовы Response.WriteSubstitution для «кэширования бублика» не работают. В первый и второй раз, когда страница загружает обратный вызов, переданный WriteSubstitution, вызывается, после чего они больше не вызываются, пока не истечет срок действия кэша вывода. Я заметил это не только с этим конкретным фильтром, но и с любым фильтром, используемым в Response.Filter ... я что-то упустил?

Я также забыл упомянуть, что пробовал это без использования атрибута фильтра действия MVC, подключившись к событию PostReleaseRequestState в global.asax и установив там значение Response.Filter ... но все равно не повезло.


person Shane Andrade    schedule 29.10.2009    source источник
comment
Если я правильно прочитал, это на самом деле специфично для ASP.NET MVC, поскольку ASP.NET не имеет такой же концепции действия. Просто примечание. :)   -  person Samantha Branham    schedule 29.10.2009
comment
Я понимаю это, но все, что я делаю, - это установка фильтра ответа. Я могу сделать это в обычном asp.net, подключившись к одному из событий жизненного цикла запроса.   -  person Shane Andrade    schedule 02.11.2009
comment
Является ли ваш код WhitespaceFilter общедоступным?   -  person Kevin Hakanson    schedule 03.11.2010


Ответы (2)


Эта статья базы знаний может дать некоторое представление об основной причине этой проблемы. Хотя фильтр «ломает» кеширование в IIS6, он выдает ошибку в IIS 7. В лучшем случае это похоже на улучшение дизайна / времени тестирования.

ОБНОВИТЬ

Вот официальный «ответ» службы поддержки MS Dev по этому поводу.

Вопрос:
Какая альтернатива фильтрации ответов в ASP.NET для изменения HTML, отображаемого другим процессом, когда:
1. Другой процесс не может быть изменен
2 . Должна поддерживаться подстановка после кеширования.

Ответ:
"Да, ваш вопрос ясен, как голубое небо, и официально заявлено, что он не поддерживается. Поскольку подстановка после кеширования будет объединять определенные блоки подстановки с байтами ответа во время фильтрации ответа ожидает фильтровать необработанные байты ответа (не измененные). Таким образом, ранее объединенные блоки подстановки больше не могут быть сохранены.

Альтернативы от Microsoft пока нет ».

person Jason Weber    schedule 03.04.2010

AFAIK, проблема в том, что фильтры действий не выполняются, если запрос попадает в выходной кеш. AuthorizeAttribute позволяет обойти эту проблему, вызывая неясный API кэша вывода. Однако я не думаю, что это лучшее решение для того, что вы пытаетесь сделать.

Вы должны работать с кешем вывода, а не вокруг него. Вместо этого вам следует убедиться, что из ответа удалены пробелы, прежде чем он будет сохранен в кеше вывода.

Обновить

Кажется, что установка фильтра, независимо от того, какой фильтр, отключает функцию WriteSubstitution, как вы и подозреваете. Я пробовал проследить след в классе HttpResponse с помощью отражателя, но не могу найти никаких доказательств, подтверждающих это подозрение. Я думаю, что ответ лежит в классе HttpWriter.

Еще одно обновление

Так получилось, что сейчас я читаю отличную книгу Стива Сандерсона «Pro ASP.NET MVC Framework» (купите ее, если у вас ее еще нет). В главе 10 ссылки на сообщение в своем блоге, где он говорит о частичном кэшировании вывода и плохая интеграция между фреймворком MVC и кешем вывода. Я еще не пробовал использовать настраиваемый атрибут outputcache в сообщении ... Я попробую его и дам вам знать, поможет ли он решить проблему.

person JohannesH    schedule 29.10.2009
comment
Да, это тот же самый вывод, к которому я пришел ... Я просмотрел код с рефлектором и не смог найти ничего, что отключило бы вызов WriteSubstitution ... Дайте мне знать, если вы найдете что-нибудь еще, но я думаю, что пока Мне просто нужно отключить фильтр ... - person Shane Andrade; 29.10.2009