[英]Correct way to compress webapi POST
I have a webform page that calls a webapi method to save some data. 我有一个webform页面,调用webapi方法来保存一些数据。 I am using the HttpClient to make the call and execute the webapi.
我正在使用HttpClient进行调用并执行webapi。
I tried to use webAPI compression to post a huge xml to the API. 我尝试使用webAPI压缩将巨大的xml发布到API。 I basically used these two websites as reference: http://www.ronaldrosier.net/blog/2013/07/16/implement_compression_in_aspnet_web_api and http://benfoster.io/blog/aspnet-web-api-compression
我基本上使用这两个网站作为参考: http : //www.ronaldrosier.net/blog/2013/07/16/implement_compression_in_aspnet_web_api和http://benfoster.io/blog/aspnet-web-api-compression
The API is working, it is triggering the handler correctly. API正在运行,它正确地触发处理程序。 I am facing some problems trying to compress and post the object, from my webforms on the server side.
我在服务器端的webforms上尝试压缩和发布对象时遇到了一些问题。
Here is the code I tried: 这是我试过的代码:
bool Error = false;
//Object to post. Just an example...
PostParam testParam = new PostParam()
{
inputXML = "<xml>HUGE XML</xml>",
ID = 123
};
try
{
using (var client = new HttpClient())
{
using (var memStream = new MemoryStream())
{
var data = new DataContractJsonSerializer(typeof(PostParam));
data.WriteObject(memStream, testParam);
memStream.Position = 0;
var contentToPost = new StreamContent(this.Compress(memStream));
contentToPost.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
contentToPost.Headers.Add("Content-Encoding", "gzip");
var response = client.PostAsync(new Uri("http://myapi/SAVE"), contentToPost).Result;
var dataReceived = response.EnsureSuccessStatusCode();
dynamic results;
if (dataReceived.IsSuccessStatusCode)
{
results = JsonConvert.DeserializeObject<dynamic>(dataReceived.Content.ReadAsStringAsync().Result);
try
{
this.Error = results.errors.Count == 0;
}
catch { }
}
}
}
}
catch
{
this.Error = true;
}
//Compress stream
private MemoryStream Compress(MemoryStream ms)
{
byte[] buffer = new byte[ms.Length];
// Use the newly created memory stream for the compressed data.
GZipStream compressedzipStream = new GZipStream(ms, CompressionMode.Compress, true);
compressedzipStream.Write(buffer, 0, buffer.Length);
// Close the stream.
compressedzipStream.Close();
MemoryStream ms1 = new MemoryStream(buffer);
return ms1;
}
When I execute the code above, it does not throw any error and in the handler, the request.Content.ReadAsStringAsync().result a huge \\0\\0\\0\\0\\0\\0... 当我执行上面的代码时,它不会抛出任何错误,并且在处理程序中,request.Content.ReadAsStringAsync()。结果是一个巨大的\\ 0 \\ 0 \\ 0 \\ 0 \\ 0 \\ 0 ...
Please, can you guys show me what I am doing wrong? 拜托,你们能告诉我我做错了什么吗? How to send the compressed object with the XML to the API correctly?
如何正确地将带有XML的压缩对象发送到API?
Thanks 谢谢
Here's what I came up with. 这就是我想出来的。 It's possible that since you aren't setting the request to accept gzip encoding, using HttpClientHandler.AutomaticDecompression , you might be getting back encoded results and aren't handling that.
有可能因为您没有设置接受gzip编码的请求,使用HttpClientHandler.AutomaticDecompression ,您可能会收回编码结果而不处理它。 That might not be it though.
可能不是这样。 In any case, I can confirm that this example works.
无论如何,我可以确认这个例子是有效的。 It is one API controller to another.
它是另一个API控制器。 Behind the scenes, I have setup WebApi to accept gzip encoding and decompress it before handing it off to the controller action;
在幕后,我已经设置WebApi接受gzip编码并解压缩,然后再将其移交给控制器动作; this is done by extending the DelegatingHandler class.
这是通过扩展DelegatingHandler类来完成的。 I let IIS do response compression.
我让IIS做响应压缩。 I use WebApi 2.
我使用WebApi 2。
public async Task<IHttpActionResult> Get()
{
List<PersonModel> people = new List<PersonModel>
{
new PersonModel
{
FirstName = "Test",
LastName = "One",
Age = 25
},
new PersonModel
{
FirstName = "Test",
LastName = "Two",
Age = 45
}
};
using (HttpClientHandler handler = new HttpClientHandler())
{
handler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
using (HttpClient client = new HttpClient(handler, false))
{
string json = JsonConvert.SerializeObject(people);
byte[] jsonBytes = Encoding.UTF8.GetBytes(json);
MemoryStream ms = new MemoryStream();
using (GZipStream gzip = new GZipStream(ms, CompressionMode.Compress, true))
{
gzip.Write(jsonBytes, 0, jsonBytes.Length);
}
ms.Position = 0;
StreamContent content = new StreamContent(ms);
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
content.Headers.ContentEncoding.Add("gzip");
HttpResponseMessage response = await client.PostAsync("http://localhost:54425/api/Gzipping", content);
IEnumerable<PersonModel> results = await response.Content.ReadAsAsync<IEnumerable<PersonModel>>();
Debug.WriteLine(String.Join(", ", results));
}
}
return Ok();
}
You can always use HttpCompression via IIS http://www.iis.net/configreference/system.webserver/httpcompression 您可以随时通过IIS使用HttpCompression http://www.iis.net/configreference/system.webserver/httpcompression
<httpCompression
directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files">
<scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" />
<dynamicTypes>
<add mimeType="text/*" enabled="true" />
<add mimeType="message/*" enabled="true" />
<add mimeType="application/javascript" enabled="true" />
<add mimeType="*/*" enabled="false" />
</dynamicTypes>
<staticTypes>
<add mimeType="text/*" enabled="true" />
<add mimeType="message/*" enabled="true" />
<add mimeType="application/javascript" enabled="true" />
<add mimeType="*/*" enabled="false" />
</staticTypes>
</httpCompression>
Then the HTTP client must initiate communication for compressed content by sending the appropriate HTTP Accept-encoding header. 然后,HTTP客户端必须通过发送适当的HTTP Accept-encoding标头来启动压缩内容的通信。
httpClient.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
Here is an example: http://benfoster.io/blog/aspnet-web-api-compression 这是一个例子: http : //benfoster.io/blog/aspnet-web-api-compression
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.