Подтвердить что ты не робот

Фильтр сжатия для веб-API

Я использовал фильтр сжатия для своих действий MVC, как описано здесь:

http://msdn.microsoft.com/en-us/magazine/gg232768.aspx

Я попытался переделать код, чтобы сделать что-то подобное для веб-API, но я попал в блокпост:

public class CompressAPIAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
    public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext filterContext)
    {
        var preferredEncoding = GetPreferredEncoding(filterContext.Request);
        Stream compressedStream = null;
        // Compress the response accordingly
        var response = filterContext.Response;
        response.Headers.Add("Content-encoding", preferredEncoding.ToString());

        if (preferredEncoding == CompressionScheme.Gzip)
        {
            response.Content = new GZipStream(compressedStream, CompressionMode.Compress); //THIS WON'T WORK
        } 

        if (preferredEncoding == CompressionScheme.Deflate)
        {
            response.Content = new DeflateStream(compressedStream, CompressionMode.Compress); //THIS WON'T WORK
        }
        return;
    }

    enum CompressionScheme
    {
        Gzip = 0,
        Deflate = 1,
        Identity = 2
    }

    private CompressionScheme GetPreferredEncoding(HttpRequestMessage request)
    {
        var acceptableEncoding = request.Headers.AcceptEncoding;

        if (acceptableEncoding.Where(h => h.Value.Contains("gzip")).Count() > 0)
            return CompressionScheme.Gzip;

        if (acceptableEncoding.Where(h => h.Value.Contains("deflate")).Count() > 0)
            return CompressionScheme.Deflate;

        return CompressionScheme.Identity;
    }

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

Я должен отметить, что это размещается в IIS 6.0, который я не контролирую.

4b9b3361

Ответ 1

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

Если вы используете IIS, выполните следующие действия для настройки сжатия (ниже приведены некоторые фрагменты от Scott Hanselman сообщение в блоге):

  • Включена функция "Динамическое сжатие" в IIS.

  • Вернитесь в диспетчер IIS, перейдите на страницу СЕРВЕР, а не САЙТ. Нажмите "Редактор конфигурации": enter image description here

  • В раскрывающемся списке выберите system.webServer/httpCompression: enter image description here

  • Затем нажмите "Динамические типы", и теперь, когда вы находитесь в редакторе списка, подумайте о том, какие типы вы хотите сжать. По умолчанию/является False, но вы можете просто включить это. Я решил быть немного более придирчивым и добавил приложение /atom + xml, application/json и application/atom + xml; charset = utf-8, как показано ниже. Немного получилось, что приложение /atom + xml и application/atom + xml; charset = utf-8 - отдельные записи. Не стесняйтесь добавлять какие-либо mimeTypes, которые вам нравятся здесь. enter image description here
  • После того, как вы добавили их и закрыли диалоговое окно, не забудьте нажать Применить и Перезагрузить вашу службу IIS для загрузки нового модуля.
  • Теперь создавайте запросы, используя заголовок Accept-Encoding, и вы должны увидеть ответ как ожидалось.

  • РЕДАКТИРОВАТЬ (помимо вышеперечисленного, включают "application/json; charset = utf-8" для покрытия обоих json-форматов)