使用HttpClient将请求压缩到asp.net core 2站点的最佳方式是什么?
问题描述:
我发送的请求可能会非常大(〜1Mb),并且在发出请求时以及处理请求时发生了很大的延迟。我想我可以通过使用gzip将请求压缩到asp来减少这个时间。使用HttpClient将请求压缩到asp.net core 2站点的最佳方式是什么?
下面是我没有压缩请求的非常直接的方式。在客户端请求方实现Gzip请求压缩的正确方法是什么,一旦我在客户端上实现它,我需要为服务器端做些什么?
using (HttpResponseMessage response = client.PostAsync("Controller/Action", httpContent).Result)
{
if (response.StatusCode != System.Net.HttpStatusCode.OK)
{
throw new Exception(string.Format("Invalid responsecode for http request response {0}: {1}", response.StatusCode, response.ReasonPhrase));
}
}
答
所以我把它用在服务器端简单的中间件并没有太多的工作就上班客户端。我使用WebAPIContrib github项目中的CompressedContent.cs,正如Rex在他的回答中提出的建议,并提出了如下所示的请求。整个抛出异常,如果不是好的,因为我正在使用Polly包裹我的请求与重试和等待策略。
客户端:
using (var httpContent = new StringContent(stringPayload, Encoding.UTF8, "application/json"))
using (var compressedContent = new CompressedContent(httpContent, "gzip"))
using (HttpResponseMessage response = client.PostAsync("Controller/Action", compressedContent).Result)
{
if (response.StatusCode != System.Net.HttpStatusCode.OK)
{
throw new Exception(string.Format("Invalid responsecode for http request response {0}: {1}", response.StatusCode, response.ReasonPhrase));
}
}
然后在服务器端我创建了一个简单的中间件的那个包裹与Gzip已流请求体流,我敢肯定你需要的应用程序之前,把中间件。 UseMvc()在配置功能中(我仍然使用ASPcore 1启动样式)。
public class GzipRequestMiddleware
{
private readonly RequestDelegate next;
private const string ContentEncodingHeader = "Content-Encoding";
private const string ContentEncodingGzip = "gzip";
private const string ContentEncodingDeflate = "deflate";
public GzipRequestMiddleware(RequestDelegate next)
{
this.next = next ?? throw new ArgumentNullException(nameof(next));
}
public async Task Invoke(HttpContext context)
{
if (context.Request.Headers.Keys.Contains(ContentEncodingHeader) && (context.Request.Headers[ContentEncodingHeader] == ContentEncodingGzip || context.Request.Headers[ContentEncodingHeader] == ContentEncodingDeflate))
{
var contentEncoding = context.Request.Headers[ContentEncodingHeader];
var decompressor = contentEncoding == ContentEncodingGzip ? (Stream)new GZipStream(context.Request.Body, CompressionMode.Decompress, true) : (Stream)new DeflateStream(context.Request.Body, CompressionMode.Decompress, true);
context.Request.Body = decompressor;
}
await next(context);
}
}
答
您可能需要启用压缩如下图所示
var handler = new HttpClientHandler();
if (handler.SupportsAutomaticDecompression)
{
handler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
}
var client = new HttpClient(handler);
一个参考MSDN链接将是完美的 –
https://blogs.msdn.microsoft.com/dotnet/2013/06/06/portable-compression-and-httpclient-working-together/ – Rex
也许我缺少一些东西,但看起来它只会处理响应解压缩而不是请求压缩,对吧? – Theyouthis