2010-05-29 10 views
9

तो मैं एक कार्रवाई फिल्टर के माध्यम से अपना उत्पादन धारा को संपीड़ित कर रहा हूँ:asp.net MVC के संपीड़ित धारा और निकालने के खाली स्थान के

var response = filterContext.HttpContext.Response; 
response.Filter = new DeflateStream(response.Filter), CompressionMode.Compress); 

कौन सा अच्छा काम करता है। अब, मैं अतिरिक्त व्हाइटस्पेस को भी हटाना चाहूंगा। मैंने मैड्स क्रिस्टेंसेन के http मॉड्यूल http://madskristensen.net/post/A-whitespace-removal-HTTP-module-for-ASPNET-20.aspx पाया।

public class WhitespaceFilter : Stream { 

    // using Mads Kristensen httpModule 
    // http://madskristensen.net/post/A-whitespace-removal-HTTP-module-for-ASPNET-20.aspx 

    private Stream os; 
    private static Regex reg = new Regex(@"^\s+", RegexOptions.Multiline | RegexOptions.Compiled); 

    public WhitespaceFilter(Stream os) { 
     this.os = os; 
    } 

    //methods that need to be overridden from stream 
    public override bool CanRead { 
     get { return true; } 
    } 

    public override bool CanSeek { 
     get { return true; } 
    } 

    public override bool CanWrite { 
     get { return true; } 
    } 

    public override void Flush() { 
     os.Flush(); 
    } 

    public override long Length { 
     get { return 0; } 
    } 

    private long _position; 
    public override long Position { 
     get { return _position; } 
     set { _position = value; } 
    } 

    public override int Read(byte[] buffer, int offset, int count) { 
     return os.Read(buffer, offset, count); 
    } 

    public override long Seek(long offset, SeekOrigin origin) { 
     return os.Seek(offset, origin); 
    } 

    public override void SetLength(long value) { 
     os.SetLength(value); 
    } 

    public override void Close() { 
     os.Close(); 
    } 

    public override void Write(byte[] buffer, int offset, int count) { 
     string html = System.Text.Encoding.Default.GetString(buffer); 

     //remove whitespace 
     html = reg.Replace(html, string.Empty); 

     byte[] outdata = System.Text.Encoding.Default.GetBytes(html); 

     //write bytes to stream 
     os.Write(outdata, 0, outdata.GetLength(0)); 
    } 

मैं WhitespaceFilter वर्ग जोड़ा गया है और संपीड़न की तरह एक नया फिल्टर कहा:

var response = filterContext.HttpContext.Response; 
response.Filter = new WhitepaperFilter(response.Filter); 

यह भी अच्छा काम करता है। हालांकि, मुझे दो संयोजनों में समस्याएं आ रही हैं!

मैंने कोशिश की:

var response = filterContext.HttpContext.Response; 
response.Filter = new DeflateStream(new WhitespaceFilter(response.Filter), CompressionMode.Compress); 

हालांकि यह कुछ प्रमुख मुद्दों का परिणाम है। एचटीएमएल पूरी तरह से गड़बड़ हो जाता है और कभी-कभी मुझे 330 त्रुटि मिलती है।

ऐसा लगता है कि व्हाइटस्पेस फ़िल्टर लेखन विधि को कई बार बुलाया जाता है। पहली बार एचटीएमएल स्ट्रिंग ठीक है, लेकिन बाद में इसे सिर्फ यादृच्छिक वर्ण कहते हैं।

मैंने सोचा कि ऐसा हो सकता है क्योंकि स्ट्रीम को डिफ्लेट किया गया था, लेकिन बिना छेड़छाड़ की धारा का उपयोग करके व्हाइटस्पेस फ़िल्टर नहीं है और फिर परिणामी स्ट्रीम को डिफ्लेटस्ट्रीम कॉल में पास कर रहा है?

कोई विचार?

+4

यदि आप इसे अभी भी संपीड़ित करने जा रहे हैं तो इसे हटाने में परेशानी क्यों है? मैं केवल इसके बारे में चिंता करता हूं अगर मैं परिणाम असंपीड़ित कर रहा था। व्हाइटस्पेस वास्तव में अच्छी तरह से संपीड़ित करता है। – tvanfosson

+2

फिडलर दिखाता है कि व्हाइटस्पेस के साथ फ़ाइल का आकार हटा दिया गया है, हालांकि एक वास्तविक दुनिया प्रोजेक्ट में, आप सही हैं; अंतर नगण्य होगा। मुझे बस दिलचस्पी है कि ऐसा क्यों नहीं चल रहा है जब ऐसा लगता है। –

+0

यदि आप व्हाइटस्पेस को संकुचित और हटाते हैं तो इस लड़के के निष्कर्ष देखें: http://stackoverflow.com/questions/855526/removing-extra-whitespace-from-generated-html-in-mvc – eadam

उत्तर

7

जो लोग इतनी दूर मिल के लिए ... आप यह कर सकते ... बस धारा के आदेश स्वैप चेनिंग:

public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     var response = filterContext.HttpContext.Response; 

     // - COMPRESS 
     HttpRequestBase request = filterContext.HttpContext.Request; 
     string acceptEncoding = request.Headers["Accept-Encoding"]; 
     if (!String.IsNullOrEmpty(acceptEncoding)) 
     { 
      acceptEncoding = acceptEncoding.ToUpperInvariant(); 

      if (acceptEncoding.Contains("GZIP")) 
      { 
       response.AppendHeader("Content-encoding", "gzip"); 
       response.Filter = new GZipStream(response.Filter, CompressionMode.Compress); 
      } 
      else if (acceptEncoding.Contains("DEFLATE")) 
      { 
       response.AppendHeader("Content-encoding", "deflate"); 
       response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress); 
      } 
     } 

     // - REMOVE WHITE SPACE 
     response.Filter = new WhitespaceFilter(response.Filter); 
    } 
+5

मैंने प्रदर्शन के साथ परीक्षण किया। रनटाइम में सफेद जगहों को ट्रिम करना भयानक है। 200 आरपीएस से यह 20 आरपीएस तक गिर गया। – BrunoLM

0

मैं ऊपर हालांकि आप इस तरीके का प्रयास कर सकते हैं कोड के साथ बहुत गलत नहीं दिखाई दे रही है:

: BTW आप जब compressing और सफेद स्थान को हटाने को लागू करने के इस विशेषता दृष्टिकोण का उपयोग कर रहे हैं

var response = filterContext.HttpContext.Response; 
using(var wsf = new WhitespaceFilter(response.Filter)) 
{ 
    wsf.Flush(); 
    response.Filter = new DefalteStream(wsf, CompressMode.Compress); 
} 

http://www.avantprime.com/articles/view-article/7/compress-httpresponse-for-your-controller-actions-using-attributes

DaTribe