2013-06-26 13 views
18

Ich habe für meine MVC Aktionen des Kompressionsfilter verwendet wie hier beschrieben:Compression Filter für Web-API

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

Ich habe versucht, den Code neu zu Zweck etwas ähnliches für Web-API zu tun , aber ich habe einen Roadblock getroffen:

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

Irgendwelche Ideen, wie ich dem Inhalt der Antwort einen komprimierten Stream zuweisen kann?

Ich sollte darauf hinweisen, dass dies in IIS 6.0 gehostet wird, die ich nicht kontrolliere.

+2

In ASP.NET Web API viel besserer Ansatz ist 'DelegatingHandler' und es gibt bereits eine Antwort, die die Lösung beschreibt http://stackoverflow.com/questions/10443588/mvc4-webapi-compress-get-method-response – tpeczek

+0

Ein Filter ermöglicht es Ihnen, nur bestimmte Webapi-Aktionen angeben ... nicht ein DelegatingHandler zwingt Sie, alle Aktionen zu komprimieren? –

Antwort

40

Ich denke, Sie sollten nicht dies in einem Action-Filter als die modelbinding Stufe vor dem Filter Aktion geschieht ausgeführt werden und während modelbinding die Formatierer könnte den Strom liest es deserialisieren, wobei in diesem Fall wäre es nicht.

Wenn Sie IIS verwenden, führen Sie dann die folgenden Setup-Kompression (die folgenden haben blog post einige Auszüge von Scott Hanselman):

  • die "Dynamic Compression" in IIS aktiviert.

  • Zurück im IIS-Manager, gehen Sie auf die Seite für die SERVER, nicht der SITE. Klicken Sie auf Configuration Editor: enter image description here

  • Aus der Dropdown-Liste wählen system.webServer/httpCompression: enter image description here

  • Klicken Sie dann auf dynamische Typen und jetzt, dass Sie in der Liste Editor sind, denken Sie an, welche Arten Sie möchte komprimiert sein. Standardmäßig ist / Falsch, aber Sie könnten das einfach einschalten. Ich wählte etwas wählerischer und fügte application/atom + xml, application/json und application/atom + xml; charset = utf-8 hinzu, wie unten zu sehen ist. Es ist ein kleiner Fehler, dass application/atom + xml und application/atom + xml; charset = utf-8 separate Einträge sind. Fühlen Sie sich frei, was auch immer MimeTypes Sie hier hinzufügen. enter image description here
  • Nachdem Sie sie hinzugefügt haben und den Dialog geschlossen, sollten Sie und Restart Ihr IIS-Dienst das neue Modul zu laden Nehmen klicken.
  • Jetzt Anfragen mit Accept-Encoding Header und Sie sollten die Antwort wie erwartet sehen.

  • EDIT (zusätzlich zu den oben schließen "application/json; charset = utf-8" beide json Formate abdecken)

+1

Gute Sachen! Leider bin ich auf IIS 6.0, ohne Kontrolle über den Server. –

+1

Hinweis: Wenn Sie nicht über den Konfigurationseditor verfügen (wie ich in IIS 7), installieren Sie einfach das Administration Pack von WebInstaller. – Kugel

+0

Falls "Accept-Encoding: deflate" nicht für mich funktioniert. – Artiom