首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >压缩HTTP GET响应

压缩HTTP GET响应
EN

Stack Overflow用户
提问于 2012-05-04 14:12:50
回答 2查看 18K关注 0票数 17

我目前正在将我的几个MVC3控制器迁移到MVC4 Api控制器上。我通过继承ActionFilterAttribute和重写OnActionExecutiong方法,实现了MVC3控制器获取方法响应的压缩机制。经过一番研究后,我发现我需要使用System.Web.HttpFilters中的ActionFilterMethod。如果有人能分享一段示例代码,让我开始使用GZip压缩HTTP响应,那就太好了

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-05-04 17:21:39

最简单的方法是直接在IIS级别执行enable compression

如果您希望在应用程序级别执行此操作,则可以编写自定义委托消息处理程序,如following post中所示

public class CompressHandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        return base.SendAsync(request, cancellationToken).ContinueWith<HttpResponseMessage>((responseToCompleteTask) =>
        {
            HttpResponseMessage response = responseToCompleteTask.Result;

            if (response.RequestMessage.Headers.AcceptEncoding != null)
            {
                string encodingType = response.RequestMessage.Headers.AcceptEncoding.First().Value;

                response.Content = new CompressedContent(response.Content, encodingType);
            }

            return response;
        },
        TaskContinuationOptions.OnlyOnRanToCompletion);
    }
}

public class CompressedContent : HttpContent
{
    private HttpContent originalContent;
    private string encodingType;

    public CompressedContent(HttpContent content, string encodingType)
    {
        if (content == null)
        {
            throw new ArgumentNullException("content");
        }

        if (encodingType == null)
        {
            throw new ArgumentNullException("encodingType");
        }

        originalContent = content;
        this.encodingType = encodingType.ToLowerInvariant();

        if (this.encodingType != "gzip" && this.encodingType != "deflate")
        {
            throw new InvalidOperationException(string.Format("Encoding '{0}' is not supported. Only supports gzip or deflate encoding.", this.encodingType));
        }

        // copy the headers from the original content
        foreach (KeyValuePair<string, IEnumerable<string>> header in originalContent.Headers)
        {
            this.Headers.AddWithoutValidation(header.Key, header.Value);
        }

        this.Headers.ContentEncoding.Add(encodingType);
    }

    protected override bool TryComputeLength(out long length)
    {
        length = -1;

        return false;
    }

    protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
    {
        Stream compressedStream = null;

        if (encodingType == "gzip")
        {
            compressedStream = new GZipStream(stream, CompressionMode.Compress, leaveOpen: true);
        }
        else if (encodingType == "deflate")
        {
            compressedStream = new DeflateStream(stream, CompressionMode.Compress, leaveOpen: true);
        }

        return originalContent.CopyToAsync(compressedStream).ContinueWith(tsk =>
        {
            if (compressedStream != null)
            {
                compressedStream.Dispose();
            }
        });
    }
}

现在剩下的就是在Application_Start中注册处理程序了

GlobalConfiguration.Configuration.MessageHandlers.Add(new CompressHandler());
票数 40
EN

Stack Overflow用户

发布于 2012-05-04 16:40:35

如果您使用的是IIS,我会说把压缩留给IIS,因为它支持7+压缩。只有turn it on

另一方面,对于控制器来说,压缩太接近金属了。理想情况下,控制器应该工作在比字节和流更高的级别。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10443588

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档