pcd*_*dev 9 c# gzip .net-4.5 dotnet-httpclient winrt-async
我们正在尝试在我们的客户端中使用用户确定(在设置屏幕上)可选的gzip压缩HttpClient
,因此我们可以在一段时间内记录和比较多个不同呼叫的性能.我们的第一次尝试是简单地有条件地添加标题如下:
HttpRequestMessage request = new HttpRequestMessage(Method, Uri);
if (AcceptGzipEncoding)
{
_client.DefaultRequestHeaders.AcceptEncoding.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("gzip"));
}
//Send to the server
result = await _client.SendAsync(request);
//Read the content of the result response from the server
content = await result.Content.ReadAsStringAsync();
Run Code Online (Sandbox Code Playgroud)
这创建了正确的请求,但是gzipped响应在返回时没有解压缩,导致响应乱码.我发现我们必须HttpClientHandler
在构建时包括HttpClient
:
HttpClient _client = new HttpClient(new HttpClientHandler
{
AutomaticDecompression = DecompressionMethods.GZip
});
Run Code Online (Sandbox Code Playgroud)
这一切都运行良好,但我们想要更改客户端是否在运行时发送Accept-Encoding: gzip
标头,并且似乎没有任何方式来访问或更改它传递给构造函数后.此外,如果对象的头部定义,则更改对象的头部对请求的头部没有任何影响.HttpClientHandler
HttpClient
HttpRequestMessage
HttpClientHandler
是否有任何方法可以在不重新创建HttpClient
每次更改的情况下执行此操作?
编辑:我也试着修改为基准HttpClientHandler
来改变AutomaticDecompression
在运行,但是这是引发此异常:
此实例已启动一个或多个请求.只能在发送第一个请求之前修改属性.
Tod*_*ier 10
你几乎就是第一个例子,你只需要自己放气.MS的GZipSteam将帮助解决这个问题:
HttpRequestMessage request = new HttpRequestMessage(Method, Uri);
if (AcceptGzipEncoding)
{
_client.DefaultRequestHeaders.AcceptEncoding.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("gzip"));
}
//Send to the server
result = await _client.SendAsync(request);
//Read the content of the result response from the server
using (Stream stream = await result.Content.ReadAsStreamAsync())
using (Stream decompressed = new GZipStream(stream, CompressionMode.Decompress))
using (StreamReader reader = new StreamReader(decompressed))
{
content = reader.ReadToEnd();
}
Run Code Online (Sandbox Code Playgroud)
如果你想使用同一个 HttpClient 并且只想对某些请求启用压缩,则无法使用自动解压。启用自动解压缩后,框架还会重置Content-Encoding
响应的标头。这意味着您无法确定响应是否真的被压缩。顺便说一句,Content-Length
如果您打开自动解压缩,响应的标头也会匹配解压缩内容的大小。
所以需要手动解压内容。以下示例显示了 gzip 压缩内容的实现(如@ToddMenier 的响应中所示):
private async Task<string> ReadContentAsString(HttpResponseMessage response)
{
// Check whether response is compressed
if (response.Content.Headers.ContentEncoding.Any(x => x == "gzip"))
{
// Decompress manually
using (var s = await response.Content.ReadAsStreamAsync())
{
using (var decompressed = new GZipStream(s, CompressionMode.Decompress))
{
using (var rdr As New IO.StreamReader(decompressed))
{
return await rdr.ReadToEndAsync();
}
}
}
else
// Use standard implementation if not compressed
return await response.Content.ReadAsStringAsync();
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
15348 次 |
最近记录: |