2013-06-26 15 views
18

Sto usando il filtro di compressione delle mie azioni MVC come dettagliato qui:filtro di compressione per l'API Web

http://msdn.microsoft.com/en-us/magazine/gg232768.aspx

Ho cercato di ri-scopo il codice per fare qualcosa di simile per l'API Web , ma ho colpito un posto di blocco:

public class CompressAPIAttribute : System.Web.Http.Filters.ActionFilterAttribute 
{ 
    public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext filterContext) 
    { 
     var preferredEncoding = GetPreferredEncoding(filterContext.Request); 
     Stream compressedStream = null; 
     // Compress the response accordingly 
     var response = filterContext.Response; 
     response.Headers.Add("Content-encoding", preferredEncoding.ToString()); 

     if (preferredEncoding == CompressionScheme.Gzip) 
     { 
      response.Content = new GZipStream(compressedStream, CompressionMode.Compress); //THIS WON'T WORK 
     } 

     if (preferredEncoding == CompressionScheme.Deflate) 
     { 
      response.Content = new DeflateStream(compressedStream, CompressionMode.Compress); //THIS WON'T WORK 
     } 
     return; 
    } 

    enum CompressionScheme 
    { 
     Gzip = 0, 
     Deflate = 1, 
     Identity = 2 
    } 

    private CompressionScheme GetPreferredEncoding(HttpRequestMessage request) 
    { 
     var acceptableEncoding = request.Headers.AcceptEncoding; 

     if (acceptableEncoding.Where(h => h.Value.Contains("gzip")).Count() > 0) 
      return CompressionScheme.Gzip; 

     if (acceptableEncoding.Where(h => h.Value.Contains("deflate")).Count() > 0) 
      return CompressionScheme.Deflate; 

     return CompressionScheme.Identity; 
    } 

Tutte le idee come posso assegnare un flusso compresso al contenuto della risposta?

Devo sottolineare che questo è ospitato in IIS 6.0, che non controllo.

+2

In ASP.NET Web API approccio molto migliore è 'DelegatingHandler' e c'è già una risposta che descrive la soluzione http://stackoverflow.com/questions/10443588/mvc4-webapi-compress-get-method-response – tpeczek

+0

Un filtro consente di specificare solo determinate azioni webapi ... non è un DelegatingHandler ti obbliga a comprimere tutte le azioni? –

risposta

40

penso che si dovrebbe non fare questo in un filtro azione come la fase modelbinding avviene prima che siano eseguiti i filtri di azione e durante modelbinding i formattatori potrebbe essere la lettura del flusso di deserializzare esso, nel qual caso fallirebbe.

Se si utilizza IIS, quindi effettuare le seguenti operazioni per la compressione di setup (Di seguito sono alcuni frammenti di Scott Hanselman di blog post):

  • abilitato la funzione "Dynamic Compression" in IIS.

  • Indietro in Gestione IIS, andare alla pagina per il SERVER, non il SITO. Clicca su Configuration Editor: enter image description here

  • Dal menu a discesa, selezionare system.webServer/httpCompression: enter image description here

  • Quindi fare clic su Tipi dinamici e ora che sei nell'editor, pensare a ciò che i tipi che si voglio compresso. Per impostazione predefinita, / è False, ma è possibile attivarlo. Ho scelto di essere un po 'più schizzinoso e ho aggiunto application/atom + xml, application/json e application/atom + xml; charset = utf-8 come visto di seguito. È un po 'logico che application/atom + xml e application/atom + xml; charset = utf-8 siano voci separate. Sentiti libero di aggiungere ciò che mai MimeTypes ti piace qui. enter image description here
  • dopo averli aggiunto e chiuso la finestra di dialogo, assicurarsi di fare clic su Applica e Restart vostro servizio IIS per caricare il nuovo modulo.
  • Ora effettuare richieste utilizzando l'intestazione Accept-Encoding e si dovrebbe vedere la risposta come previsto.

  • EDIT (in aggiunta a sopra includere "application/json; charset = utf-8" per coprire entrambi i formati JSON)

+1

Roba buona! Sfortunatamente, sono su IIS 6.0, senza controllo sul server. –

+1

Nota: se non si dispone di Configuration Editor (come me in IIS 7), installare Administration Pack da WebInstaller – Kugel

+0

In caso di "Accept-Encoding: deflate" non funziona per me. – Artiom

Problemi correlati