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 ---