c# - 可以在 ASP.NET/IIS 7 中有选择地禁用 gzip 压缩吗?

标签 c# asp.net asp.net-mvc-3 iis-7 compression

我正在使用长期异步 HTTP 连接通过 AJAX 向客户端发送进度更新。启用压缩后,不会以离散 block 的形式接收更新(原因很明显)。禁用压缩(通过将 <urlCompression> 元素添加到 <system.webServier> )确实解决了问题:

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

但是,这会在站点范围内禁用压缩。我想为除此之外的所有其他 Controller 和/或操作保留压缩。这可能吗?或者我是否必须使用自己的 web.config 创建一个新站点/区域?欢迎提出任何建议。

附言写入 HTTP 响应的代码是:

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

最佳答案

@Aristos 的回答适用于 WebForms,但在他的帮助下,我采用了更符合 ASP.NET/MVC 方法的解决方案。

创建一个新过滤器以提供 gzip 压缩功能:

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");
            } 
        }
    }
}

创建 NoGzip 属性:

public class NoGzipAttribute : Attribute {
}

使用 web.config 阻止 IIS7 压缩:

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

在 Global.asax.cs 中注册您的全局过滤器:

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

最后,使用NoGzip属性:

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

    public ActionResult GetProgressCompleted() 
    {
        ...
    }
}

附言再次非常感谢@Aristos,感谢他提供的有益想法和解决方案。

关于c# - 可以在 ASP.NET/IIS 7 中有选择地禁用 gzip 压缩吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5656332/

相关文章:

asp.net-mvc - 仅从路线数据生成 URL

c# - 基于类型变量实例化不同存储库的策略模式

c# - 为什么不能推断出嵌套的泛型类型?

c# - asp.net mvc 自定义模型绑定(bind)

c# - Entity Framework .edmx.sql 文件如何在已部署的应用程序中生成数据库?

asp.net - 高流量 ASP.NET MVC 编码注意事项

asp.net - 混合自定义和默认模型绑定(bind)

asp.net-mvc - 从类中删除必需的属性,但MVC3仍然不会在文本框中没有值的情况下发布表单

C# 单元测试模拟方法不起作用(为什么?)

ASP.NET 5 MVC (Visual Studio 2015) : a keyword called Inject