jru*_*ell 5 asp.net-mvc gzip asp.net-mvc-3
我在ASP.NET MVC 3中使用gzip/deflate ActionFilterAttribute时遇到了一个有趣的问题.如果我的应用程序抛出异常,而不是获得YSOD,我会得到一整页乱码,如下所示.
I?%&/m?{J?J??t??$ @ iG#)* eVe] f @ 흼 { { ; N' ?\fdl !???Jɞ〜|"安永")= y6hZ2kjuU + _ X-: T W v <[ ~2 g 2 ? ʋ y hYՋ t _N M l { , Xn Q } *g 7 ~?j'u>K?{_??IW4?>?U?w?|=-fYzR-???????|??<&?o?Z()*?S!U??k?g???????j??.????b}????9X/??J?I???Q???z?i?n?-g???????Y^????H?8/??k?}]7??@?{|?g??wUd?O?????y???o-????????? ?ZHv,?d]????>o3?=?3x?7MN???????????Ow???w?.o????<?M????;???vg???A>???{Y?N???????$p>q????/?!?y??9?2??two?????????????????n?9?r?^????!??????{???ag??\1*c??!?b?? xI u f? {' P$ v&=#s l _0 w ss 廌 ⼽ r ! [KP\7M(O4ߛ>> @"|| vy5QꆦRJSK& ߛ p v< C t 1 hOI y{j ]i ˷ ˷ D'p< $,?'M??r{-?}??CF???????A??9??[?½?? ?! 2?? ?:??!??{?t?;??'y??M??+?M^#x^\????Q??jM?l???(?]? ??IZ??[????+4#"?:?X????m???????dv>??????iL??I |?fL?TU??ho?? ?{L??_t??5?o????h?O?UY]#?u?[???G???=???;??8???~????d?8k?w?????yw?ֺ NXA [XMO F /噩; Y〜!
如果我删除我的CompressAttribute,它按预期工作(我看到YSOD).所以我的异常处理(ElmahHandleErrorAttribute来自Elmah.Contrib.Mvc)似乎停止了剩余的过滤器,包括CompressAttribute并且响应没有缩小.
相关代码:
public sealed class CompressAttribute : ActionFilterAttribute
{
private const string _acceptEncodingHeader = "Accept-Encoding";
private const string _contentEncodingHeader = "Content-Encoding";
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
HttpRequestBase request = filterContext.HttpContext.Request;
string acceptEncoding = request.Headers[_acceptEncodingHeader];
if (String.IsNullOrEmpty(acceptEncoding))
{
return;
}
acceptEncoding = acceptEncoding.ToUpperInvariant();
HttpResponseBase response = filterContext.HttpContext.Response;
if (acceptEncoding.Contains("GZIP"))
{
response.AppendHeader(_contentEncodingHeader, "gzip");
response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
}
else if (acceptEncoding.Contains("DEFLATE"))
{
response.AppendHeader(_contentEncodingHeader, "deflate");
response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
}
}
}
Run Code Online (Sandbox Code Playgroud)
过滤注册:
GlobalFilterCollection filters = GlobalFilters.Filters;
filters.Add(new ElmahHandleErrorAttribute(), 999); // Elmah.Contrib.Mvc
filters.Add(new CompressAttribute());
Run Code Online (Sandbox Code Playgroud)
即使抛出异常,如何确保响应是可读的?
这是一个稍微好一点的答案,灵感来自于iaimtomisbe的回答.它允许您将所有代码保留在一个类中.
将以下覆盖添加到CompressAttribute类:
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
if (filterContext.Exception != null)
{
filterContext.HttpContext.Response.Filter = null;
}
}
Run Code Online (Sandbox Code Playgroud)
这是因为当您的应用程序出现错误时,ASP.Net会删除所有自定义标题,但过滤器仍然存在.您可以根据应用程序错误重置过滤器,以避免问题消失.
protected void Application_Error(object sender, EventArgs e)
{
Response.Filter = null;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
657 次 |
| 最近记录: |