2011-04-13 21 views
10

Estoy usando una conexión HTTP asincrónica de larga duración para enviar actualizaciones de progreso a un cliente a través de AJAX. Cuando la compresión está habilitada, las actualizaciones no se reciben en fragmentos discretos (por razones obvias). La desactivación de compresión (mediante la adición de un elemento <urlCompression>-<system.webServier>) no resuelve el problema:¿Se puede deshabilitar selectivamente la compresión de gzip en ASP.NET/IIS 7?

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

Sin embargo, esto desactiva todo el sitio-compresión. Me gustaría conservar la compresión para cada otro controlador y/o acción, excepto para este. es posible? ¿O voy a tener que crear un nuevo sitio/área con su propio web.config? Cualquier sugerencia bienvenida

P.S. el código que hace que la escritura es la respuesta HTTP:

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

Respuesta

12

@Aristos' funcionará para formularios Web, pero con su ayuda, me he adaptado una solución más en línea con la metodología ASP.NET/MVC.

crear un nuevo filtro para proporcionar la funcionalidad gzipping:

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

crear el atributo NoGzip:

public class NoGzipAttribute : Attribute { 
} 

Prevenir IIS7 de gzipping utilizando web.config:

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

Registre su filtro global en Global.asax.cs:

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

Por último, consumen el atributo NoGzip:

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

    public ActionResult GetProgressCompleted() 
    { 
     ... 
    } 
} 

P. S. Una vez más, muchas gracias a @Aristos por su útil idea y solución.

3

¿Y se establece la compresión gzip por su cuenta propia, selectivle cuando se desea para? En Application_BeginRequest, compruebe cuándo desea realizar y cuándo no realiza la compresión. Aquí hay un código de muestra. respuesta

protected void Application_BeginRequest(Object sender, EventArgs e) 
{ 
    string cTheFile = HttpContext.Current.Request.Path; 
    string sExtentionOfThisFile = System.IO.Path.GetExtension(cTheFile); 

    if (sExtentionOfThisFile.Equals(".aspx", StringComparison.InvariantCultureIgnoreCase)) 
    { 
     string acceptEncoding = MyCurrentContent.Request.Headers["Accept-Encoding"].ToLower();; 

     if (acceptEncoding.Contains("deflate") || acceptEncoding == "*") 
     { 
      // defalte 
      HttpContext.Current.Response.Filter = new DeflateStream(prevUncompressedStream, 
       CompressionMode.Compress); 
      HttpContext.Current.Response.AppendHeader("Content-Encoding", "deflate"); 
     } else if (acceptEncoding.Contains("gzip")) 
     { 
      // gzip 
      HttpContext.Current.Response.Filter = new GZipStream(prevUncompressedStream, 
       CompressionMode.Compress); 
      HttpContext.Current.Response.AppendHeader("Content-Encoding", "gzip"); 
     }  
    } 
} 
+0

gracias por su ayuda. He utilizado su guía para crear la solución que describo en mi respuesta. –

4

Encontré una manera mucho más fácil de hacer esto. En lugar de hacer selectivamente su propia compresión, puede desactivar selectivamente la compresión IIS predeterminada (suponiendo que esté habilitada en su web.config).

Simplemente elimine el encabezado de codificación de aceptación de codificación en la solicitud y IIS no comprime la página.

(global.asax.cs :)

protected void Application_BeginRequest(object sender, EventArgs e) 
{ 
    try 
    { 
     HttpContext.Current.Request.Headers["Accept-Encoding"] = ""; 
    } 
    catch(Exception){} 
} 
+1

Es una práctica extremadamente mala modificar los encabezados * request * del lado * server *. Básicamente estás pirateando el servidor para forjar los encabezados de las solicitudes y modificar el comportamiento del lado del servidor. Eso es tenso, por decir lo menos. –

Cuestiones relacionadas