MVC全局GZIP压缩,异常黄页出现乱码解决方案
最近这个问题一直让我很纠结,设置了MVC全局压缩后发现,连抛出异常的页面也会进行压缩,于是出现一连串压缩后的乱码,感觉实在是太坑爹了。其中一直在想既然能压缩,那就肯定可以解压缩,于是一直试啊试,还是没成功,试过读取写入流,解压缩,试过用系统的方法,可是都没用,唉,那时候感觉真的一团糟啊,在国外的一些技术交流社区也提过问,可是都没得到理想的答案,经过这几天的努力,不过最主要的还是我们项目经理—小亮的指导,我完成了这么一个让我很纠结的压缩的问题。好了,不多说了,开始上代码吧。
首先来看看我定义的CompressFilterAttribute过滤器吧。
1 /// <summary> 2 /// 文件压缩特性 3 /// </summary> 4 public class CompressFilterAttribute : ActionFilterAttribute 5 { 6 private bool isEnableCompression = true; 7 8 /// <summary> 9 /// 构造函数 10 /// </summary> 11 public CompressFilterAttribute() 12 { 13 } 14 15 #region OnActionExecuting 16 /// <summary> 17 /// Action方法执行前执行的方法 18 /// </summary> 19 /// <param name="filterContext">ActionExecutingContext 对象</param> 20 public override void OnActionExecuting(ActionExecutingContext filterContext) 21 { 22 object[] actionFilter = filterContext.ActionDescriptor.GetCustomAttributes(typeof(NoCompress), false); 23 object[] controllerFilter = filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(typeof(NoCompress), false); 24 if (controllerFilter.Length == 1 || actionFilter.Length == 1) 25 { 26 isEnableCompression = false; 27 } 28 } 29 #endregion 30 31 #region OnResultExecuted 32 /// <summary> 33 /// 返回结果集之后执行的方法 34 /// </summary> 35 /// <param name="filterContext"></param> 36 public override void OnResultExecuted(ResultExecutedContext filterContext) 37 { 38 if (filterContext.HttpContext.Request.IsAjaxRequest()) 39 { 40 return; 41 } 42 43 if (filterContext.Exception != null) 44 { 45 return; 46 } 47 48 if (isEnableCompression) 49 { 50 HttpRequestBase request = filterContext.HttpContext.Request; 51 HttpResponseBase response = filterContext.HttpContext.Response; 52 string acceptEncoding = request.Headers["Accept-Encoding"]; 53 54 if (acceptEncoding == null) 55 { 56 return; 57 } 58 59 if (acceptEncoding.ToLower().Contains("gzip")) 60 { 61 response.Filter = new GZipStream(response.Filter, CompressionMode.Compress); 62 response.AppendHeader("Content-Encoding", "gzip"); 63 } 64 else if (acceptEncoding.ToLower().Contains("deflate")) 65 { 66 response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress); 67 response.AppendHeader("Content-Encoding", "deflate"); 68 } 69 } 70 #endregion 71 }
文中运用到的排除压缩方法是:http://www.cnblogs.com/yangda/archive/2013/03/20/2970860.html
首先在OnActionExecuting方法呢是判断当前Controller或者Action方法是否贴有特性[NoCompress],当贴有我们就直接跳过,不对其进行压缩。
OnResultExecuted便是真正的对代码进行压缩的语句了,判断当前是否为AJAX请求,判断当前是否出现错误,出现这些情况都排除,不对其进行压缩。
开始想的太复杂了,后来仔细分析了一下,也就是在出现错误的时候我们不对其进行压缩,页面也就不会出现乱码了。
重点代码是:filterContext.Exception != null ,判断其之前是否出现过异常。出现后,不执行压缩,直接抛出错误页面。