2010-05-29 41 views
9

Vì vậy, tôi nén dòng đầu ra của tôi qua một bộ lọc hành động:asp.net dòng nén MVC và loại bỏ khoảng trắng

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

Những tác phẩm tuyệt vời. Bây giờ, tôi cũng muốn loại bỏ khoảng trống dư thừa hiện tại. Tôi đã tìm thấy mô-đun http của Mads Kristensen 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)); 
    } 

tôi đã thêm lớp WhitespaceFilter và thêm một bộ lọc mới như nén:

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

này cũng làm việc tuyệt vời. Tuy nhiên, tôi dường như gặp vấn đề khi kết hợp cả hai!

tôi đã cố gắng:

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

Tuy nhiên kết quả này trong một số vấn đề lớn. Các html được hoàn toàn sai lầm và đôi khi tôi nhận được một lỗi 330.

Dường như phương pháp ghi bộ lọc khoảng trắng được gọi nhiều lần. Lần đầu tiên chuỗi html là tốt, nhưng trên các cuộc gọi tiếp theo chỉ là ký tự ngẫu nhiên của nó.

Tôi nghĩ có thể là do luồng đã bị xì hơi, nhưng không phải bộ lọc khoảng trắng sử dụng luồng không bị ảnh hưởng và sau đó truyền luồng kết quả đến cuộc gọi DeflateStream?

Bất kỳ ý tưởng nào?

+4

Tại sao bạn phải xóa nó nếu bạn vẫn định nén nó? Tôi chỉ lo lắng về điều đó nếu tôi đang cung cấp kết quả không nén. Khoảng trắng nén thực sự tốt. – tvanfosson

+2

Fiddler không cho thấy rằng với khoảng trống đã loại bỏ kích thước tệp nhỏ hơn một chút, tuy nhiên trong một dự án thế giới thực, bạn đã đúng; sự khác biệt sẽ không đáng kể. Tôi chỉ quan tâm đến lý do tại sao điều này không làm việc khi nó có vẻ như nó nên. –

+0

Xem các phát hiện của anh chàng này nếu bạn nén và xóa khoảng trắng: http://stackoverflow.com/questions/855526/removing-extra-whitespace-from-generated-html-in-mvc – eadam

Trả lời

7

Đối với những người có được điều này xa ... bạn có thể làm điều đó ... chỉ cần hoán đổi thứ tự của các dòng chaining:

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

Tôi đã thực hiện kiểm tra với hiệu suất. Cắt tỉa khoảng trắng trong thời gian chạy là khủng khiếp. Từ 200 rps nó giảm xuống còn 20 rps. – BrunoLM

0

Tôi không nhìn thấy nhiều sai với đoạn code trên tuy nhiên bạn có thể muốn thử phương pháp này:

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

BTW bạn đang sử dụng cách tiếp cận thuộc tính này khi áp dụng nén và không gian trắng xoá:

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

DaTribe

Các vấn đề liên quan