2016-07-28 129 views
3

使用:C#,MVC 5,IIS 8ActionFilter響應類型(文本/ HTML)不匹配的響應內容

我想實現一個ActionFilter將壓縮HTML。這裏的基本方法是將響應的Stream替換爲將輸入寫入MemoryStream的自定義Stream,然後使用Close方法縮小存儲在MemoryStream中的內容並寫出(縮小的)內容。

我遇到的問題是雖然響應的類型是'text/html',但傳遞給自定義流的內容不是而是看起來像text或html,它看起來像二進制文件。我應該補充一點,我的網站頁面渲染得很好,所以無論內容是什麼,都不是完全垃圾。我添加了一些日誌語句來調試,這就是它們的樣子:

縮小誤差|塊:1 |網址:/Login/iFrameLogin.aspx | 編碼:System.Text.UTF8Encoding | MediaType:text/html |內容:

我也嘗試關閉我的網站上的動態壓縮,也沒有任何改變。 有沒有人有任何想法,爲什麼我的'文本/ HTML'看起來像二進制?

FilterAttribute

public class MinifyHtmlFilterAttribute : ActionFilterAttribute 
{ 
    public override void OnResultExecuted(ResultExecutedContext filterContext) 
    { 
     HttpContextBase context = filterContext.HttpContext; 
     HttpRequestBase request = context.Request; 
     HttpResponseBase response = context.Response; 
     Encoding encoding = response.ContentEncoding; 
     string mediaType = response.ContentType; 
     string currentUrl = request.RawUrl; 
     var minificationManager = HtmlMinificationManager.Current; 

     if (response.Filter != null 
      && response.StatusCode == 200 
      && minificationManager.IsSupportedMediaType(mediaType) //text/html 
      && minificationManager.IsProcessablePage(currentUrl)) 
     { 
      response.Filter = new HtmlMinificationFilterStream(response, minificationManager, currentUrl, encoding, mediaType); 
     } 
    } 
} 

自定義流

public class HtmlMinificationFilterStream : Stream 
{ 
    private readonly HttpResponseBase _response; 
    private readonly Stream _stream; 
    private readonly MemoryStream _cacheStream = new MemoryStream(); 

    private readonly IMarkupMinificationManager _minificationManager; 

    private readonly string _currentUrl; 
    private readonly Encoding _encoding; 
    private readonly string _mediaType; 
    private int _chunkCount = 0; 

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

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

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

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

    public override long Position 
    { 
     get; 
     set; 
    } 

    public HtmlMinificationFilterStream(HttpResponseBase response, 
     IMarkupMinificationManager minificationManager, 
     string currentUrl, 
     Encoding encoding, 
     string mediaType) 
    { 
     _response = response; 
     _stream = response.Filter; 
     _minificationManager = minificationManager; 
     _currentUrl = currentUrl; 
     _encoding = encoding; 
     _mediaType = mediaType; 
    } 

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

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

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

    public override void Write(byte[] buffer, int offset, int count) 
    { 
     _cacheStream.Write(buffer, 0, count); 
     _chunkCount++; 
    } 

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

    public override void Close() 
    { 
     byte[] cacheBytes = _cacheStream.ToArray(); 
     int cacheSize = cacheBytes.Length; 
     string content = _encoding.GetString(cacheBytes); 
     var log = $" | Chunks: {_chunkCount} | Url: {_currentUrl} | Encoding: {_encoding} | MediaType: {_mediaType} | Content: {content}"; 

     IMarkupMinifier minifier = _minificationManager.CreateMinifier(); 
     MarkupMinificationResult minificationResult = minifier.Minify(content, _currentUrl, _encoding, false); 
     bool isMinified = false; 
     if (minificationResult.Errors.Count == 0) 
     { 
      ExceptionHandler.LogException("MINIFICATION SUCCESS" + log, System.Diagnostics.EventLogEntryType.Warning); 
      using (var writer = new StreamWriter(_stream, _encoding)) 
      { 
       writer.Write(minificationResult.MinifiedContent); 
      } 

      isMinified = true; 
     } 
     else 
     { 
      foreach (var error in minificationResult.Errors) 
      { 
       ExceptionHandler.LogException("Minification Error" + log + " | " + error.SourceFragment, System.Diagnostics.EventLogEntryType.Warning); 
      } 
     } 

     if (!isMinified) 
     { 
      _cacheStream.Seek(0, SeekOrigin.Begin); 
      _cacheStream.CopyTo(_stream); 
     } 

     _cacheStream.SetLength(0); 
     _stream.Close(); 
    } 
} 
+0

你確定你的代碼真的是最後執行的東西嗎?也許二進制流是一種內部格式,然後還有另一個進程,通常不可見地將其轉換回輸出的東西? – fastmultiplication

+0

終於弄明白了(有點) - 這是IIS壓縮設置。當我關閉IIS上的壓縮時,我的流看起來如何我期望。 – Rosemary

回答

0

關閉壓縮在IIS(8)修復該問題。

相關問題