Now Webapi more and more popular, often it is used to do interface return JSON format data, WEBAPI originally based on the type of client is dynamically serialized to JSON and XML, but in fact, many times we are serialized into JSON, So WEBAPI serialization is more time consuming than we use servicestack.text serialization, and if the amount of data returned is larger then we should start gzip and deflate compression. And these implementations must not affect the existing code, I personally like to also be accustomed to using features to complete the compression and JSON formatting.
1. Compressed code:
namespacemvcapp{usingSystem; usingSystem.Collections.Generic; usingSystem.IO; usingSystem.Linq; usingsystem.web; usingSystem.Web.Http.Filters; usingSystem.IO.Compression; usingSystem.Net.Http; Public classCompressattribute:actionfilterattribute { Public Override voidonactionexecuted (Httpactionexecutedcontext actionexecutedcontext) {varContent =actionExecutedContext.Response.Content; varacceptencoding = actionExecutedContext.Request.Headers.AcceptEncoding.Where (x = = X.value = ="gzip"|| X.value = ="deflate"). ToList (); if(Acceptencoding! =NULL&& Acceptencoding.count >0&& Content! =NULL&& ActionExecutedContext.Request.Method! =httpmethod.options) {varbytes =content. Readasbytearrayasync (). Result; if(Acceptencoding.firstordefault (). Value = ="gzip") {actionExecutedContext.Response.Content=Newbytearraycontent (compressionhelper.gzipcompress (bytes)); ACTIONEXECUTEDCONTEXT.RESPONSE.CONTENT.HEADERS.ADD ("content-encoding","gzip"); } Else if(Acceptencoding.firstordefault (). Value = ="deflate") {actionExecutedContext.Response.Content=Newbytearraycontent (compressionhelper.deflatecompress (bytes)); ACTIONEXECUTEDCONTEXT.RESPONSE.CONTENT.HEADERS.ADD ("content-encoding","deflate"); } } Base. OnActionExecuted (ActionExecutedContext); } } classCompressionhelper { Public Static byte[] Deflatecompress (byte[] data) { if(Data = =NULL|| Data. Length <1) returndata; Try { using(MemoryStream stream =NewMemoryStream ()) { using(Deflatestream GZipStream =NewDeflatestream (Stream, compressionmode.compress)) {gzipstream.write (data,0, data. Length); Gzipstream.close (); } returnStream. ToArray (); } } Catch(Exception) {returndata; } } Public Static byte[] Gzipcompress (byte[] data) { if(Data = =NULL|| Data. Length <1) returndata; Try { using(MemoryStream stream =NewMemoryStream ()) { using(GZipStream GZipStream =NewGZipStream (Stream, compressionmode.compress)) {gzipstream.write (data,0, data. Length); Gzipstream.close (); } returnStream. ToArray (); } } Catch(Exception) {returndata; } } }}
First determine whether the client starts Gzip,deflate compression, if enabled and the request type is not the options and returns data, then we compress the returned data. As for gzip or deflate, see if the client accepts a compression of gzip,deflate?
2.json
As follows:
Public ienumerable<users> Get ()
{
return _userlist;
}
Many times we will change the return type of this API to httpresponsemessage data that is serialized in JSON format, written as a common method for everyone to invoke. I recommend the implementation to use attribute to do.
Related code:
namespacemvcapp{usingServicestack.text; usingSystem; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Net; usingSystem.Net.Http; usingSystem.Reflection; usingSystem.Text; usingsystem.web; usingSystem.Web.Http.Controllers; usingSystem.Web.Http.Filters; Public classJsonresultconverterattribute:actionfilterattribute { Public Override voidonactionexecuting (System.Web.Http.Controllers.HttpActionContext actioncontext) {//ActionContext.ActionDescriptor.ResultConverter; varActiondescriptor =Actioncontext.actiondescriptor; varfield =typeof(Httpactiondescriptor). GetField ("_converter", BindingFlags.NonPublic |bindingflags.instance); if(Field! =NULL) {field. SetValue (Actiondescriptor,NewJsonresultconverter ()); //Actiondescriptor.returntype = typeof (Httpresponsemessage); } varTest =Actiondescriptor.resultconverter; Base. OnActionExecuting (Actioncontext); } } Public classJsonresultconverter:iactionresultconverter { PublicHttpresponsemessage Convert (Httpcontrollercontext controllercontext,ObjectActionResult) { if(ControllerContext = =NULL) { Throw NewArgumentNullException ("ControllerContext"); } httpresponsemessage resultasresponse= ActionResult asHttpresponsemessage; if(Resultasresponse! =NULL) { //resultasresponse.ensureresponsehasrequest (controllercontext.request); returnResultasresponse; } stringJsonresult =typeserializer.serializetostring (ActionResult); varContent =NewStringcontent (Jsonresult, Encoding.UTF8,"Application/json"); returncontrollerContext.Request.CreateResponse (Httpstatuscode.ok, Jsonresult); } }}
Note that the private field of the Httpactiondescriptor _converter is exposed in the Resultconverter attribute, unfortunately a read-only property, So we need to use reflection to set its value (implement the Iactionresultconverter interface).
Running results I don't have stickers anymore, code: http://download.csdn.net/detail/dz45693/9486586
ASP. NET WebAPi gzip compression and JSON format