发送压缩响应的Web API问题

时间:2015-02-09 03:41:27

标签: c# json asp.net-web-api compression httpresponse

我一直在努力让gzip / deflate压缩处理Web API响应。我一直在使用Github - MessageHandlers.Compression中的代码。然而,它似乎没有奏效。 Google开发人员控制台或Firefox中的Firebug中没有出现Content-Encoding标头,并且Content-Length始终设置为未压缩的数据大小。所以我一直在删除代码,直到我得到以下内容:

protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
    // Send the request to the web api controller
    var response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);

    // Compress uncompressed responses from the server
    if (response.Content != null && request.Headers.AcceptEncoding.IsNotNullOrEmpty())
    {
        var content = response.Content;
        var bytes = content.ReadAsByteArrayAsync().Result;

        if (bytes != null && bytes.Length > 1024)
        {
            // The data has already been serialised to JSon by this point
            var compressedBytes = Compress(bytes);
            response.Content = new ByteArrayContent(compressedBytes);

            var headers = response.Content.Headers;
            headers.Remove("Content-Type");
            headers.ContentLength = compressedBytes.Length;
            headers.ContentEncoding.Clear();
            headers.ContentEncoding.Add("gzip");
            headers.Add("Content-Type", "application/json");
        }
    }

    return response;
}

private static byte[] Compress(byte[] input)
{
    using (var compressStream = new MemoryStream())
    {
        using (var compressor = new GZipStream(compressStream, CompressionMode.Compress))
        {
            compressor.Write(input, 0, input.Length);
            compressor.Close();
            return compressStream.ToArray();
        }
    }
}

当我最初这样做时,我犯了一个错误,并将标题中的内容编码设置为&#39; gzip&#39;当我在Compress方法中使用DeflateStream时。正如您所料,我在浏览器中出现错误,但响应标头是正确的(!)。也就是说,设置了Content-Encoding标头并且Content-Length是正确的。同样,查看原始数据我可以清楚地看到是否已压缩。一旦我纠正了我的错误,但问题又回来了。

我想知道的是,最新版本的浏览器会在后台解压缩内容,还是我的代码确实有问题?响应以Json格式发送

任何帮助都非常感激。

修改

我尝试使用Global.asax中的以下方法将标头转储到日志文件中(按日志中出现的顺序列出):

Application_PreSendRequestHeaders

Application_EndRequest

Application_PreSendRequestContent

在每种情况下,所需的标题都在那里,即使它们没有出现在Google开发者控制台中。然后,我在Code Project查看了解决方案。从命令行运行时,一切都按预期工作。但是,当我从谷歌浏览器调用Web服务器时,我得到了完全相同的结果。也就是说,没有Content-Encoding标头,也没有关于内容是否已被压缩的指示。但是,在开发人员控制台打开的情况下,很容易在其他站点看到此标头(例如,堆栈溢出)。因此,我必须假设这与来自web api服务的压缩响应有关。如果这实际上是客户端的话,那就很难知道了。

1 个答案:

答案 0 :(得分:3)

如果有人不想阅读所有评论,答案来自Jerry Hewett(jerhewet)。也就是说,反病毒软件在到达浏览器之前拦截响应。反病毒软件解压缩数据,无疑是扫描过程的一部分。非常感谢Jerry在这里的帮助。