2012-02-14 17 views
4

/ASP.NET MVC 3でActionFilterAttributeを収縮不全を収縮させる、私は完全なページを取得します下に見られるように不器用です。 GZIP /私はgzipで興味深い問題がある

I�%&/m�{J�J��t�� $ @ F iGに#)* EVE] @흼

{{; N」 \\ ɞ ɞ ɞ 〜〜| | """ )))))= 6 U + _x-: TWV < [〜2G2ʋyhYՋトン? _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ي?xIuf ?{ 'Pの$のV & =#sl_0΃wss 廌⼽⼽ r ! {k \ 7M ( 4 ߛ V < Ct1hOIy {j]は 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�を私ֺのNx [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); 
     } 
    } 
} 

フィルター登録:

GlobalFilterCollection filters = GlobalFilters.Filters; 
filters.Add(new ElmahHandleErrorAttribute(), 999); // Elmah.Contrib.Mvc 
filters.Add(new CompressAttribute()); 

がどのように応答は、例外がスローされた場合でも読み取り可能であることを確認することができますか?

+0

私は、http圧縮を有効にするための他の/より良い方法にもオープンしています。 – jrummell

+0

IISに組み込まれている動的圧縮を調べましたか? –

+0

@amit_g私はしていません。リンクがありますか? – jrummell

答えて

6

アプリケーションでエラーが発生した場合ASP.Netは、すべてのカスタムヘッダーを削除しますが、フィルタがまだあるためです。問題を解消する必要があるアプリケーションエラーでフィルタをリセットすることができます。

protected void Application_Error(object sender, EventArgs e) 
{ 
     Response.Filter = null; 
} 
+0

これはうまくいった、ありがとう! – jrummell

+0

@jrummell素晴らしい、これがあなたが探していたものなら答えを受け入れることができますか? – sarvesh

8

ここでは、iaimtomisbehaveの答えに触発されて、少し良い答えがあります。 1つのクラス内にすべてのコードを保持することができます。

あなたCompressAttributeクラスに次のオーバーライドを追加します。

public override void OnResultExecuted(ResultExecutedContext filterContext) 
{ 
    if (filterContext.Exception != null) 
    { 
     filterContext.HttpContext.Response.Filter = null; 
    } 
} 
+0

これは実際に私がやったことです。 – jrummell

+1

これは、OnActionExecutedに配置してもOnResultExecutedに配置しないと機能します。 – andrewpm

0

は、同じ問題の解決のためにインターネットをGoogleで検索して、ここで終わりました。非常に有益な回答が、私の次のバージョンを実装するよう促しました。

static public void EnableGzip() 
{ 
    var c = HttpContext.Current; 
    string a = c.Request.Headers["Accept-Encoding"]; 
    if (String.IsNullOrEmpty(a)) 
     return; 
    if (!a.Contains("gzip")) 
     return; 
    c.Response.Filter = new GZipStream(
     c.Response.Filter, CompressionMode.Compress); 
    c.Response.AppendHeader("Content-Encoding", "gzip"); 
    EventHandler errorHandler = null; 
    errorHandler = delegate 
    { 
     c.Response.Filter = null; 
     c.ApplicationInstance.Error -= errorHandler; 
    }; 
    c.ApplicationInstance.Error += errorHandler; 
} 

これを批判してください。

関連する問題