压缩HTTP GET响应

Pav*_*ula 17 c# http-compression asp.net-web-api

我目前正在努力将我的一些MVC3控制器迁移到MVC4 Api控制器.我已经通过inherting ActionFilterAttribute和overriding方法实现了MVC3控制器获取方法响应的压缩机制OnActionExecutiong.经过一番研究,我发现,我需要使用ActionFilterMethodSystem.Web.HttpFilters.如果有人可以分享一些示例代码,让我开始使用GZip压缩HTTP响应,那将是很棒的

Dar*_*rov 40

最简单的方法是直接在IIS级别启用压缩.

如果要在应用程序级别执行此操作,可以编写自定义委派消息处理程序,如以下帖子所示:

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();
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

现在剩下的就是在以下位置注册处理程序Application_Start:

GlobalConfiguration.Configuration.MessageHandlers.Add(new CompressHandler());
Run Code Online (Sandbox Code Playgroud)


Ali*_*tad 6

如果您使用的是IIS 7+,我会说压缩到IIS,因为它支持GZIP压缩.只需打开它.

另一方面,压缩太靠近控制器的金属.理想情况下,控制器应该在比字节和流更高的级别上工作.