可以gzip压缩COM pression在ASP.NET/IIS 7有选择地禁止? [英] Can gzip compression be selectively disabled in ASP.NET/IIS 7?

查看:139
本文介绍了可以gzip压缩COM pression在ASP.NET/IIS 7有选择地禁止?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是长寿命的异步HTTP连接通过AJAX进度更新发送到客户端。当启用COM pression,更新不会离散块收到(原因很明显)。禁用COM pression(通过添加< urlCom pression> 元素< system.webServier> )的确实的解决这个问题:

 < urlCom pression doStaticCom pression =真doDynamicCom pression =FALSE/>

不过,这种禁用COM pression站点范围。我想preserve COM pression的除了这个其他所有控制器和/或采取行动。这可能吗?还是我将不得不创建具有自身Web.config的网站/地区?任何建议表示欢迎。

P.S。在code,做了书面的HTTP响应是:

  VAR响应= HttpContext.Response;
RESPONSE.WRITE(S);
response.Flush();


解决方案

@Aristos的回答将为WebForms的工作,但在他的帮助,我已经适应与ASP.NET/MVC方法的解决方案更直列。

创建新的过滤器,以提供gzip压缩功能:

 公共类GzipFilter:ActionFilterAttribute
{
    公共覆盖无效OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);        VAR语境= filterContext.HttpContext;
        如果(filterContext.Exception == NULL和放大器;&安培;
            context.Response.Filter = NULL&放大器;!&安培;
            !filterContext.ActionDescriptor.IsDefined(typeof运算(NoGzipAttribute),真))
        {
            字符串acceptEncoding = context.Request.Headers [的Accept-Encoding]。ToLower将();;            如果(acceptEncoding.Contains(gzip的))
            {
                context.Response.Filter =新GZipStream(context.Response.Filter,COM pressionMode.Com preSS);
                context.Response.AppendHeader(内容编码,gzip的);
            }
            否则,如果(acceptEncoding.Contains(放气))
            {
                context.Response.Filter =新DeflateStream(context.Response.Filter,COM pressionMode.Com preSS);
                context.Response.AppendHeader(内容编码,放气);
            }
        }
    }
}

NoGzip 属性:

 公共类NoGzipAttribute:属性{
}

prevent IIS7使用gzip压缩的web.config:

 < system.webServer>
    ...
    < urlCom pression doStaticCom pression =真doDynamicCom pression =FALSE/>
< /system.webServer>

填写您的全局过滤器在Global.asax.cs中:

 保护无效的Application_Start()
{
    ...
    GlobalFilters.Filters.Add(新GzipFilter());
}

最后,消耗 NoGzip 属性:

 公共类myController的:AsyncController
{
    [NoGzip]
    [NoAsyncTimeout]
    公共无效GetProgress(INT ID)
    {
        AsyncManager.OutstandingOperations.Increment();
        ...
    }    公众的ActionResult GetProgressCompleted()
    {
        ...
    }
}

P.S。再次,非常感谢@Aristos,他有益的观点和解决方案。

I am using a long-lived asynchronous HTTP connection to send progress updates to a client via AJAX. When compression is enabled, the updates are not received in discrete chunks (for obvious reasons). Disabling compression (by adding a <urlCompression> element to <system.webServier>) does solve the problem:

<urlCompression doStaticCompression="true" doDynamicCompression="false" />

However, this disables compression site-wide. I would like to preserve compression for every other controller and/or action except for this one. Is this possible? Or am I going to have to create a new site/area with its own web.config? Any suggestions welcome.

P.S. the code that does the writing to the HTTP response is:

var response = HttpContext.Response;
response.Write(s);
response.Flush();

解决方案

@Aristos' answer will work for WebForms, but with his help, I've adapted a solution more inline with ASP.NET/MVC methodology.

Create a new filter to provide the gzipping functionality:

public class GzipFilter : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);

        var context = filterContext.HttpContext;
        if (filterContext.Exception == null && 
            context.Response.Filter != null &&
            !filterContext.ActionDescriptor.IsDefined(typeof(NoGzipAttribute), true))
        {
            string acceptEncoding = context.Request.Headers["Accept-Encoding"].ToLower();;

            if (acceptEncoding.Contains("gzip"))
            {
                context.Response.Filter = new GZipStream(context.Response.Filter, CompressionMode.Compress);
                context.Response.AppendHeader("Content-Encoding", "gzip");
            }                       
            else if (acceptEncoding.Contains("deflate"))
            {
                context.Response.Filter = new DeflateStream(context.Response.Filter, CompressionMode.Compress);
                context.Response.AppendHeader("Content-Encoding", "deflate");
            } 
        }
    }
}

Create the NoGzip attribute:

public class NoGzipAttribute : Attribute {
}

Prevent IIS7 from gzipping using web.config:

<system.webServer>
    ...
    <urlCompression doStaticCompression="true" doDynamicCompression="false" />
</system.webServer>

Register your global filter in Global.asax.cs:

protected void Application_Start()
{
    ...
    GlobalFilters.Filters.Add(new GzipFilter());
}

Finally, consume the NoGzip attribute:

public class MyController : AsyncController
{
    [NoGzip]
    [NoAsyncTimeout]
    public void GetProgress(int id)
    {
        AsyncManager.OutstandingOperations.Increment();
        ...
    }

    public ActionResult GetProgressCompleted() 
    {
        ...
    }
}

P.S. Once again, many thanks to @Aristos, for his helpful idea and solution.

这篇关于可以gzip压缩COM pression在ASP.NET/IIS 7有选择地禁止?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆