HttpClient and Aps.net Web API: Compression and decompression of request content

Source: Internet
Author: User

First of all, the compression and decompression here is not the usual HTTP compression--that is the response content on the server compression, decompression on the client, and here is the request content in the client compression, decompression on the server.

For compression of the response content, the general Web server (such as IIS) provides built-in support that includes accept-encoding:gzip in the request header, deflate , and the client browser and HttpClient provide built-in decompression support. The code for enabling this compression in HttpClient is as follows:

var New HttpClient (new httpclienthandler {automaticdecompression =     | System.Net.DecompressionMethods.Deflate});

For compression of the requested content. NET HttpClient does not provide built-in support, IIS also does not provide the built-in support for decompression, need to write code implementation, this article is born.

Why compress the content of the request? Currently we encounter in 2 scenarios: 1) You need to submit large text data when calling a third-party web api;2 with HttpClient or iOS app calling your own web API.

For compression and decompression, the corresponding class library--gzipstream and Deflatestream are available in System.IO.Compression, and we only need to apply them in the HttpClient and Web APIs.

Let's take a look at the implementation of client httpclient. We need to implement a httpcontent--compressedcontent that supports compression, the implementation code is as follows:

 Public enumcompressionmethod{GZip=1, Deflate=2} Public classcompressedcontent:httpcontent{Private ReadOnlyhttpcontent _originalcontent; Private ReadOnlyCompressionmethod _compressionmethod;  Publiccompressedcontent (httpcontent content, Compressionmethod compressionmethod) {if(Content = =NULL)        {            Throw NewArgumentNullException ("content"); } _originalcontent=content; _compressionmethod=Compressionmethod; foreach(keyvaluepair<string, ienumerable<string>> Headerinch_originalcontent.headers) {headers.tryaddwithoutvalidation (header). Key, header.        Value); } Headers.ContentEncoding.Add (_compressionmethod.tostring ().    Tolowerinvariant ()); }    protected Override BOOLTrycomputelength ( out Longlength) {Length= -1; return false; }    protected Async OverrideTask Serializetostreamasync (Stream stream, TransportContext context) {if(_compressionmethod = =compressionmethod.gzip) {using(varGZipStream =NewGZipStream (Stream, compressionmode.compress, Leaveopen:true))            {                await_originalcontent.copytoasync (GZipStream); }        }        Else if(_compressionmethod = =compressionmethod.deflate) {using(varDeflatestream =NewDeflatestream (Stream, compressionmode.compress, Leaveopen:true))            {                await_originalcontent.copytoasync (Deflatestream); }        }    }}

The main thing is the overloaded Httpcontent.serializetostreamasync () method, in which compression is used with the appropriate compression algorithm.

HttpClient Use this compressedcontent method as follows:

var json = jsonconvert.serializeobject (bookmark); var New compressedcontent (    new"application/json"),     Compressionmethod.gzip); var await _httpclient.postasync ("/api/bookmarks", content);

Take a look at the implementation in the server-side ASP. NET Web API, you need to implement a delegatinghandler--decompressionhandler:

 Public classdecompressionhandler:delegatinghandler{protected Override AsyncTaskSendAsync (httprequestmessage request, CancellationToken CancellationToken) {if(Request. Method = =httpmethod.post) {BOOLIsgzip = Request. Content.Headers.ContentEncoding.Contains ("gzip"); BOOLIsdeflate =!isgzip && request. Content.Headers.ContentEncoding.Contains ("deflate"); if(Isgzip | |isdeflate) {Stream Decompressedstream=NewMemoryStream (); if(isgzip) {using(varGZipStream =NewGZipStream (awaitrequest.                        Content.readasstreamasync (), compressionmode.decompress)) { awaitGzipstream.copytoasync (Decompressedstream); }                }                Else if(isdeflate) {using(varGZipStream =NewDeflatestream (awaitrequest.                        Content.readasstreamasync (), compressionmode.decompress)) { awaitGzipstream.copytoasync (Decompressedstream); }} decompressedstream.seek (0, Seekorigin.begin); varOrigincontent =request.                Content; Request. Content=Newstreamcontent (Decompressedstream); foreach(varHeaderinchorigincontent.headers) {request. CONTENT.HEADERS.ADD (header. Key, header.                Value); }            }        }        return await Base.    SendAsync (Request, CancellationToken); }}

Overloads the Delegatinghandler.sendasync () method, in which the decompression operation is done with GZipStream or deflatestream.

Then apply this decompressionhandler in Webapiconfig, with the following code:

 Public Static class webapiconfig{    publicstaticvoid  Register (httpconfiguration config)    {        config. Messagehandlers.add (new  Decompressionhandler ());}    }

Finally, with this support request content compression HttpClient call this support request content decompression of the Web API test, with Wireshark to see if compression is effective.

Test success!

Resources

How to compress HTTP request on the fly and without loading compressed buffer in memory

How does enable a. Net Web-api to accept g-ziped posts

HTTP Message Handlers in ASP Web API

Compressed HTTP Requests

HttpClient and Aps.net Web API: Compression and decompression of request content

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.