c# - 发送压缩响应的 Web API 问题

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

我一直致力于让 gzip/deflate 压缩对 Web API 响应起作用。我一直在使用 Github - MessageHandlers.Compression 中的代码.但是它似乎没有用。 Google Developer 控制台或 Firefox 的 Firebug 中没有出现 Content-Encoding header ,并且 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();
        }
    }
}

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

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

非常感谢任何帮助。

编辑

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

Application_PreSendRequestHeaders

Application_EndRequest

Application_PreSendRequestContent

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

最佳答案

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

关于c# - 发送压缩响应的 Web API 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28402460/

相关文章:

c# - 如何使用 DOT 文件导出数据?

c# - 如何通过 C# 中指定的 FileStream.Position 和长度获取字符串

c# - 反序列化期间的 JSON.Net Ignore Property

ios - 将iOS中的一列JSON文件解析为数组?

java - Jackson JSON 处理器问题

java - 使用 Jackson 根据 API 版本指定不同的 JSON 属性名称

javascript - 如何从 JavaScript 调用通用 WebAPI 操作?

c# - Window 最上面的困惑——又没有出路?

asp.net - 在 ASP.NET 中自定义授权作为过滤器或在 Controller 的构造函数中?

c# - 从.net core 2.1中的单例服务注入(inject)作用域服务