利用 ActionFilter 为 ASP.NET Web API 添加 GZip 压缩功能

时间:2022-04-20 20:01:54

直接上代码

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 == null ? new byte[0] :
CompressionHelper.DeflateByte(bytes);
actContext.Response.Content = new ByteArrayContent(zlibbedContent);
actContext.Response.Content.Headers.Remove("Content-Type");
actContext.Response.Content.Headers.Add("Content-encoding", "deflate");
actContext.Response.Content.Headers.Add("Content-Type", contentType);
base.OnActionExecuted(actContext);
}
}

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

using (var output = new MemoryStream())
{
using (var compressor = new Ionic.Zlib.DeflateStream(output, Ionic.Zlib.CompressionMode.Compress, Ionic.Zlib.CompressionLevel.BestSpeed))
{
compressor.Write(str, 0, str.Length);
}

return output.ToArray();
}
}
}

使用 DeflateCompression 来标记需要压缩的 Web API

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

}
}

备注

  • 增加对 Request 中 Accept-Encoding 设定的判断,如果客户端请求包含压缩请求才进行压缩
  • 示例利用了第三方库来进行,可以视情况来自定义替换为其他库