2016-07-28 69 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)修复该问题。

相关问题