1. 程式人生 > >webapi 利用 ActionFilter 為 ASP.NET Web API 新增 GZip 壓縮功能

webapi 利用 ActionFilter 為 ASP.NET Web API 新增 GZip 壓縮功能

webapi 利用 ActionFilter 為 ASP.NET Web API 新增 GZip 壓縮功能

先直接上程式碼
    /// <summary>
    /// 對結果進行壓縮處理
    /// </summary>
    public class DeflateCompressionAttribute : ActionFilterAttribute
    {

        public override void OnActionExecuted(HttpActionExecutedContext actContext)
        {
            var contentType = actContext.Response.Content.Headers.ContentType.ToString();
            var content = actContext.Response.Content;
            var bytes = content == null ? null : content.ReadAsByteArrayAsync().Result;
            //var zlibbedContent = bytes;

            var zipTypeId = GZipSupportedTypeId(actContext);
            if (zipTypeId > 0)
            {
                if (zipTypeId == 1)
                {
                    var zlibbedContent = CompressionHelper.GzipDeflateByte(bytes);
                    actContext.Response.Content = new ByteArrayContent(zlibbedContent);
                    actContext.Response.Content.Headers.Remove("Content-Type");
                    actContext.Response.Content.Headers.Add("Content-Encoding", "gzip");
                    actContext.Response.Content.Headers.Add("Content-Type", contentType);
                }
                ////deflate壓縮有問題
                //if (zipTypeId == 2)
                //{
                //    zlibbedContent = CompressionHelper.DeflateByte(bytes);
                //    actContext.Response.Content.Headers.Add("Content-Encoding", "deflate");
                //}
            }


            base.OnActionExecuted(actContext);
        }

        /// <summary>
        /// Determines if GZip is supported; 0=no support,1=gzip,2=deflate
        /// </summary>
        /// <returns></returns>
        public static int GZipSupportedTypeId(HttpActionExecutedContext actContext)
        {
            var typeId = 0;
            string acceptEncoding = actContext.Request.Headers.AcceptEncoding.ToString();
            if (!string.IsNullOrEmpty(acceptEncoding) &&
                (acceptEncoding.Contains("gzip") || acceptEncoding.Contains("deflate")))
            {
                if (acceptEncoding.Contains("deflate"))
                {
                    typeId = 2;
                }
                if (acceptEncoding.Contains("gzip"))
                {
                    typeId = 1;
                }
            }
            return typeId;
        }

        public class CompressionHelper
        {
            public static byte[] DeflateByte(byte[] str)
            {
                if (str == null)
                {
                    return null;
                }

                using (var output = new MemoryStream())
                {
                    using (var compressor = new DeflateStream(output, System.IO.Compression.CompressionMode.Compress))
                    {
                        compressor.Write(str, 0, str.Length);
                    }

                    return output.ToArray();
                }
            }


            public static byte[] GzipDeflateByte(byte[] str)
            {
                if (str == null)
                {
                    return null;
                }

                using (var output = new MemoryStream())
                {
                    if (true)
                    {
                        using (var gzip = new GZipStream(output, CompressionMode.Compress))
                        {
                            gzip.Write(str, 0, str.Length);
                        }
                    }
                    return output.ToArray();
                }
            }
        }
    }

public class V1Controller : ApiController
{
    [DeflateCompression]
    public HttpResponseMessage GetCustomers()
    {

    }

或在全域性處理的地方統一加也行

config.filters.Add(new DeflateCompressionAttribute());
config 為 HttpConfiguration
備註

增加對 Request 中 Accept-Encoding 設定的判斷,如果客戶端請求包含壓縮請求才進行壓縮

被註釋的部分是利用了第三方庫來進行,可以視情況來自定義替換為其他庫


--- end ---