2012-01-12 14 views
5

मैं एक कस्टम HttpHandler जिसमें मैं मैन्युअल रूप से उत्पादन संपीड़न सक्षम इसलिए की तरह है, तो गायब हो जाता है:"सामग्री एन्कोडिंग" शीर्षक HttpHandler प्रतिक्रिया से एक अपवाद तब होता है

context.Response.AppendHeader("Content-encoding", "gzip"); 
context.Response.Filter = new GZipStream(context.Response.Filter, CompressionMode.Compress); 

यह सबसे अनुरोध के लिए अच्छी तरह से काम करता है, लेकिन जब एक अपवाद का सामना "सामग्री-एन्कोडिंग" हेडर प्रतिक्रिया से गायब हो जाता है, जबकि संपीड़न फ़िल्टर जगह में रहता है। नतीजा यह है कि त्रुटि पृष्ठ gzip संपीड़ित है, लेकिन ब्राउज़र को उस तथ्य को इंगित करने वाला कोई हेडर प्राप्त नहीं होता है। ब्राउज़र फिर भी संकुचित डेटा को पाठ के रूप में प्रदर्शित करने का प्रयास करता है, जो gobbledygook है।

पूर्ण परीक्षण केस कोड नीचे दिखाया गया है। संपीड़न को वैकल्पिक रूप से अक्षम करने या अपवाद फेंकने का प्रयास करें।

क्या कोई भी "सामग्री-एन्कोडिंग" हेडर गायब होने पर कुछ प्रकाश डाल सकता है?

मुझे लगता है कि मैं पिछले हैंडलर की चीज के रूप में संपीड़न को सक्षम कर सकता हूं, ताकि यदि कोई अपवाद सामने आया तो यह उस बिंदु तक नहीं पहुंचता जहां संपीड़न फ़िल्टर जोड़ा जाता है; लेकिन जो व्यवहार मैं देख रहा हूं वह मुझे एक बग के रूप में मारता है। क्या कोई पुष्टि कर सकता है?

public class TestHandler : IHttpHandler 
{ 
    public void ProcessRequest(HttpContext context) 
    { 
     CompressResponse(context); 
     context.Response.Write("Hello world"); 

     // Throw an exception for testing purposes 
     throw new Exception("Just testing..."); 
    } 

    private void CompressResponse(HttpContext context) 
    { 
     string acceptEncoding = context.Request.Headers["Accept-Encoding"]; 
     if (String.IsNullOrEmpty(acceptEncoding)) 
     { 
      return; 
     } 

     // gzip or wildcard 
     if (acceptEncoding.ToLower().Contains("gzip") || acceptEncoding.Contains("*")) 
     { 
      context.Response.AppendHeader("Content-encoding", "gzip"); 
      context.Response.Filter = new GZipStream(context.Response.Filter, CompressionMode.Compress); 
      return; 
     } 

     // Also handles deflate (not shown here) 
     // <snip> 
    } 

    public bool IsReusable 
    { 
     get { return true; } 
    } 
} 

संपादित करें: अभी भी एन्कोड प्रतिक्रिया का स्क्रीनशॉट मैं अपने परीक्षण मामले के साथ दिखाई दे रही है: http://i.imgur.com/49Vcl.png

उत्तर

-1

मैं अपने कोड का परीक्षण और मैं किसी भी मुद्दे को नहीं मिल रहा। हां gzip सेट नहीं है, लेकिन फ़िल्टर भी सेट नहीं किया गया है और एएसपी नियंत्रण प्राप्त करता है और एक त्रुटि भेजता है।

हैडर जबरदस्ती अगर मैं gzip हैडर के लिए मजबूर तो पेज ठीक से प्रदर्शित नहीं कर रहा है एक वास्तविक समस्या

CompressResponse(context); 
context.Response.Flush(); 

बनाने फ्लश करने के लिए।

दो सोचते हैं कि शायद आपका मुद्दा है। आप पृष्ठ एन्कोडिंग

context.Response.ContentEncoding = new UTF8Encoding(); 

निर्धारित किया है नहीं है और आप ContentType

context.Response.ContentType = "text/plain"; 

निर्धारित किया है नहीं है हो सकता है कि इनमें से कुछ कारण यह है कि आप को सही पेज रेंडर नहीं मिल रहा है। मेरे परीक्षणों में भी इस बात के साथ कि आपके द्वारा वर्णित समस्या प्रकट नहीं होती है।

+0

तो यदि आप मेरे कोड को निष्पादित करते हैं, तो आपको अभी भी संपीड़ित gobbledygook की बजाय उचित पीले-स्क्रीन-मौत मिलती है? –

+0

हां, जैसा कि है, मैं प्रतिलिपि/पेस्ट बना देता हूं और मुझे उचित पीले रंग की स्क्रीन मिलती है। समस्या तब प्रकट होती है जब मैं फ्लश करता हूं() !!!!!!!! क्या आप त्रुटि से पहले कहीं फ्लश करते हैं? Gzip प्रकट नहीं होता है, लेकिन फ़िल्टर भी सेट नहीं है। – Aristos

+0

शायद कहीं और आपने कस्टम त्रुटि सेट की है? – Aristos

0

यदि आपके पास अपवाद है, तो सर्वर वर्तमान में सेट हेडर और सामग्री को फ्लश करेगा, क्योंकि वे गलत हैं, जैसा कि आपने सभी को निष्पादन के बाद किया था।

कम से कम, यह स्पष्ट है कि 200 स्थिति जो आप भेजने जा रहे थे (क्योंकि सभी सफल प्रतिक्रियाएं जो स्थिति को नहीं बदलती हैं 200 भेजती हैं, और एक अनचाहे अपवाद पर यह अब सफल नहीं था) गलत है, लेकिन कुछ और जो आप करने जा रहे थे उससे संबंधित सब कुछ लेकिन हासिल करने में असफल रहा, इसलिए यह सब गलत है और यह सब चला जाता है।

फ़िल्टर हालांकि रीसेट नहीं किए जाते हैं।

या तो उपयुक्त होने पर हेडर को त्रुटि पृष्ठ में रीसेट करें, या फ़िल्टर सेट न करें जब तक आप सुनिश्चित न हों कि सब कुछ फ्लश करने के लिए तैयार है। मैं पूर्व के लिए जाऊंगा, कोई कारण नहीं कि त्रुटि पृष्ठों को भी संपीड़ित नहीं किया जा सकता है।

यदि आप Flush() कहलाते हैं, तो आप हेडर नहीं भेज सकते हैं, क्योंकि आप फ्लश कर चुके हैं। हेडर कहां जा रहा है?

+0

तो जब कोई त्रुटि होती है, तो हैंडलर किसी भी शीर्षलेख और सामग्री को हटा देता है जो लिखा गया है (लेकिन अभी तक फ्लश नहीं किया गया है), लेकिन मैंने जो फिल्टर डाला है उसे हटाने के लिए उपेक्षा करता है? –

+0

हां। यह परेशान है, लेकिन मुझे लगता है कि फिल्टर पाइपलाइन में उच्च स्तर पर अवधारणात्मक रूप से बैठने के लिए था, इसलिए यह किसी के लिए समझ में आया ... –

+0

ऐसा लगता है कि अगर त्रुटि हैंडलर हेडर को हटा देता है तो मैंने लिखा होगा मेरे द्वारा असाइन किए गए फ़िल्टर को हटा दें। मुझे आश्चर्य है कि यह एक बग है, या डिज़ाइन द्वारा ... अन्यथा, क्या आप "200 स्थिति जो आप भेजने जा रहे थे" से क्या मतलब है, यह स्पष्ट कर सकते हैं? अपवाद हैंडलर 500 स्थिति निर्धारित करता है। मुझे मैन्युअल रूप से 200 से अधिक स्थिति क्यों सेट करनी चाहिए? –

0

मुझे इस समस्या का भी सामना करना पड़ा। यह ट्रैक करने के लिए जटिल था। मैं इस पूरी स्थिति के सटीक विनिर्देशों से अनिश्चित हूं, लेकिन मुझे लगता है कि ऐसा होता है कि एक स्मृति रिसाव है।

जब आप पहली बार ऐसा करते हैं:

context.Response.Filter = new GZipStream(context.Response.Filter, CompressionMode.Compress); 

आप Filter के लिए एक अप्रबंधित संसाधन बताए जाते हैं। आम तौर पर इसे using कथन में लपेटा जाएगा ताकि कुछ गलत होने पर ठीक से निपटान किया जा सके

तो, जब कुछ गलत हो जाता है, तो कोई समस्या होती है। Filter में एक स्ट्रीम है जो अभी भी खुली है, भले ही प्रतिक्रिया मौत की पीली स्क्रीन के साथ लिखी जा रही हो। पागलपन क्या होता है (जैसा कि आपके स्क्रीन शॉट में दिखाया गया है)।

डरो मत! वास्तव में इस मुद्दे को दूर करने का एक आसान तरीका है। फ़िल्टर का निपटान करें। सौभाग्य से, फ़िल्टर निपटान के लिए इस वैश्विक जांच को लागू करने के लिए पहले से ही एक जगह है।

global.asax.cs

public static void RegisterGlobalFilters(GlobalFilterCollection filters) 
{ 
     filters.Add(new HandleErrorAttribute());//default handler 
     filters.Add(new HandleErrorEncodingAttribute());//extra check for filter disposal 
} 

त्रुटि हैंडलर नाम स्थान

public class HandleErrorEncodingAttribute : FilterAttribute, IExceptionFilter 
{ 
    public virtual void OnException(ExceptionContext filterContext) 
    { 
     if (filterContext == null) 
     { 
      throw new ArgumentNullException("filterContext"); 
     } 
     if (filterContext.IsChildAction) 
     { 
      return; 
     } 
     // If custom errors are disabled, we need to let the normal ASP.NET exception handler 
     // execute so that the user can see useful debugging information. 
     if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled) 
     { 
      filterContext.HttpContext.Response.Filter.Dispose();//fixes response stream 
      return; 
     } 
    } 
} 
0

मैं एक ही बात हो सकता है जब एक WebForms आवेदन पर gzip के लिए मजबूर कर दिया था। आदेश इसे ठीक करने के लिए मैं कारण यह हो रहा है से पहले एप्लिकेशन में त्रुटि है फ़िल्टर सेट की जा रही है b/c है Global.asax.cs

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

में Application_Error विधि में फिल्टर स्पष्ट करने के लिए किया था । और किसी कारण से पीले रंग की स्क्रीन संदेश सामग्री-एन्कोडिंग हेडर को साफ़ करता है लेकिन प्रतिक्रिया फ़िल्टर में कुछ भी नहीं करता है।

संबंधित मुद्दे

 संबंधित मुद्दे