I have a webform page that calls a webapi method to save some data. I am using the HttpClient to make the call and execute the webapi.
I tried to use webAPI compression to post a huge xml to the 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
The API is working, it is triggering the handler correctly. I am facing some problems trying to compress and post the object, from my webforms on the server side.
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...
Please, can you guys show me what I am doing wrong? How to send the compressed object with the XML to the API correctly?
Thanks
To use compression, include the HTTP header Accept-Encoding: gzip or Accept-Encoding: deflate in a request. The REST API compresses the response if the client properly specifies this header. The response includes the header Content-Encoding: gzip or Accept-Encoding: deflate .
Use a compression header to compress a REST API request or response. Compression reduces the bandwidth required for a request, although it requires more processing power at your client. In most cases, this tradeoff benefits the overall performance of your application.
The abundance and easy availability of CPU at the expense of network bandwidth can be a good reason to use content compression in Web API for faster responses and improved performance. Web API is the technology of choice for building RESTful web services in . Net.
However, you must configure your API to enable compression of the method response payload. To enable compression on an API , set the minimumCompressionsSize property to a non-negative integer between 0 and 10485760 (10M bytes) when you create the API or after you've created the API.
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. That might not be it though. In any case, I can confirm that this example works. It is one API controller to another. Behind the scenes, I have setup WebApi to accept gzip encoding and decompress it before handing it off to the controller action; this is done by extending the DelegatingHandler class. I let IIS do response compression. I use 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
<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.
httpClient.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
Here is an example: http://benfoster.io/blog/aspnet-web-api-compression
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With