Asp.net FilterAttribute冲突压缩,RegexFilter

Asp.net FilterAttribute冲突压缩,RegexFilter,asp.net,asp.net-mvc-3,compression,action-filter,Asp.net,Asp.net Mvc 3,Compression,Action Filter,我有这样一个控制器动作 [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, s

我有这样一个控制器动作

[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);
regex响应过滤器基于一篇博客文章。注意,我并没有试图删除空白,我只是想插入一个纸条标签,但这是无关的

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);
    }
}
这可能是显而易见的,但这看起来应该有效。应在压缩发生之前应用插入


非常感谢

尝试翻转包含顺序:

[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
时相同,然后使用一个操作过滤器属性将两个流组合起来