所以我通过动作过滤器压缩输出流:
var response = filterContext.HttpContext.Response;
response.Filter = new DeflateStream(response.Filter), CompressionMode.Compress);
哪个效果很好。现在,我还想删除多余的空白。我找到了Mads Kristensen的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);
然而,这会导致一些重大问题。 html完全搞砸了,有时我得到330错误。
似乎多次调用Whitespace过滤器写入方法。第一次html字符串很好,但在后续调用时只是随机字符。
我认为这可能是因为流已被缩小,但不是使用未触动的流的空白过滤器,然后将结果流传递给DeflateStream调用?
有什么想法吗?
答案 0 :(得分: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);
}
答案 1 :(得分:0)
上面的代码我没有看到太大的错误,但你可能想尝试这种方法:
var response = filterContext.HttpContext.Response;
using(var wsf = new WhitespaceFilter(response.Filter))
{
wsf.Flush();
response.Filter = new DefalteStream(wsf, CompressMode.Compress);
}
BTW在应用压缩和空白删除时使用此属性方法:
DaTribe