2011-06-08 44 views
0

我有像这样FilterAttributes冲突的压缩,RegexFilter

[AcceptVerbs(HttpVerbs.Get | HttpVerbs.Put)] 
[InsertScript(Order = 1)] 
[Compress(Order = 2)] 
public ViewResult Service(Page page) { //omitted } 

控制器动作的InsertScript属性施加Response.Filter

response.Filter = new RegexResponseFilter(response.Filter, scriptInsertRegex, replacementString); 

正则表达式响应滤波器是基于一个博客帖子here。注意我不想删除空格,我试图插入脚本标记,但这是无关紧要的。

RegexResponseFilter的写入方法如此。其余与blogpost相同。

public override void Write(byte[] buffer, int offset, int count) 
{ 
    // capture the data and convert to string 
    var data = new byte[count]; 
    Buffer.BlockCopy(buffer, offset, data, 0, count); 

    // filter the string 
    var s = Encoding.Default.GetString(buffer); 
    s = regex.Replace(s, replacement); 

    // write the data to stream 
    var outdata = Encoding.Default.GetBytes(s); 
    response.Write(outdata, 0, outdata.GetLength(0)); 
} 

这很好的孤立。但是当我应用一个压缩属性(在互联网上的任何地方都可以看到相当标准的属性)时,事情就会打破FF4的错误信息。

您尝试查看的页面无法显示,因为它使用无效或不受支持的压缩形式。

我闻到了一个红鲱鱼,并删除了InsertScript属性,它的工作原理。所以这两者在某种程度上是相互冲突的。这是完整性的压缩属性。

public class CompressAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     //get request and response 
     var request = filterContext.HttpContext.Request; 
     var response = filterContext.HttpContext.Response; 

     //get encoding 
     var encoding = request.Headers["Accept-Encoding"]; 
     if (string.IsNullOrWhiteSpace(encoding)) 
      return; 

     encoding = encoding.ToUpperInvariant(); 


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

     base.OnActionExecuting(filterContext); 
    } 
} 

这可能是显而易见的,但看起来它应该工作。插入物应在压缩发生之前应用。

非常感谢

回答

0

尝试翻转包容的顺序:

[AcceptVerbs(HttpVerbs.Get | HttpVerbs.Put)] 
[Compress(Order = 1)] 
[InsertScript(Order = 2)] 
public ViewResult Service(Page page) { //omitted } 

另一种可能性是多个过滤器结合这样的,然后使用一个单一的行为过滤器属性:

response.Filter = new CompressStream(new InsertScript(response.Filter)); 

对于这个工作你需要写一个自定义的CompressStream类,就像你使用InsertScript一样,然后有一个单一的动作f ilter属性将组合这两个流。