57 votes

Comment compresser un résultat Json à partir d'ASP.NET MVC avec IIS 7.5 ?

J'ai des difficultés à faire en sorte que IIS 7 compresse correctement un résultat Json à partir d'ASP.NET MVC. J'ai activé la compression statique et dynamique dans IIS. Je peux vérifier avec Fiddler que les enregistrements normaux de type text/html et similaires sont compressés. En regardant la requête, l'en-tête accept-encoding gzip est présent. La réponse a le mimetype "application/json", mais n'est pas compressée.

J'ai identifié que le problème semble être lié au MimeType. Lorsque j'inclus mimeType="*/*" Je peux voir que la réponse est correctement gzippée. Comment puis-je faire en sorte que IIS compresse SANS utiliser de joker mimeType ? Je suppose que ce problème a quelque chose à voir avec la façon dont ASP.NET MVC génère les en-têtes de type de contenu.

L'utilisation du processeur est bien en dessous du seuil d'étranglement dynamique. Lorsque j'examine les journaux de suivi de IIS, je constate que la compression échoue parce qu'elle ne trouve pas de type mime correspondant.

<httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files" noCompressionForProxies="false">
    <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" />
    <dynamicTypes>
        <add mimeType="text/*" enabled="true" />
        <add mimeType="message/*" enabled="true" />
        <add mimeType="application/x-javascript" enabled="true" />
        <add mimeType="application/json" enabled="true" />
    </dynamicTypes>
    <staticTypes>
        <add mimeType="text/*" enabled="true" />
        <add mimeType="message/*" enabled="true" />
        <add mimeType="application/x-javascript" enabled="true" />
        <add mimeType="application/atom+xml" enabled="true" />
        <add mimeType="application/xaml+xml" enabled="true" />
        <add mimeType="application/json" enabled="true" />
    </staticTypes>
</httpCompression>

1 votes

Je ne peux pas utiliser un mimetype joker car je rencontre un problème étrange avec IE8 - il semble avoir des difficultés à télécharger un fichier .zip lorsque la demande est encore compressée par IIS. Firefox 3.5 n'est pas affecté.

62voto

deerchao Points 5517

Assurez-vous que votre %WinDir \System32\inetsrv\config\applicationHost.config contient ceux-ci :

<system.webServer>
    <urlCompression doDynamicCompression="true" />
    <httpCompression>
      <dynamicTypes>
        <add mimeType="application/json" enabled="true" />
        <add mimeType="application/json; charset=utf-8" enabled="true" />       
      </dynamicTypes>
    </httpCompression>
</system.webServer>

De la lien de @AtanasKorchev.

Comme @simon_weaver l'a dit dans les commentaires, vous modifiez peut-être le mauvais fichier avec un éditeur 32 bits sur un Windows 64 bits, utilisez notepad.exe pour vous assurer que ce fichier est bien modifié.

2 votes

NTOE : si applicationHost.config Il me semble que vous êtes probablement sur une machine 64 bit utilisant un éditeur 32 bit. Essayez notepad APRÈS AVOIR FAIT UNE SAUVEGARDE bien sûr. west-wind.com/weblog/posts/2008/Aug/09/

0 votes

Des heures, des heures je vous dis, j'ai passé des HEURES à essayer de découvrir pourquoi mon application/json gzippée ne sortait pas de mon IIS... Cela a finalement fonctionné ! Merci !

0 votes

N'oubliez pas d'effectuer un recyclage vers le pool d'applications.

22voto

Atanas Korchev Points 20945

J'ai utilisé avec succès l'approche mise en avant aquí .

10 votes

J'avais déjà vu cet article, mais je l'avais écarté car il n'apportait rien de nouveau ou d'utile. Eh bien, il semble que, contrairement aux autres types de mime, vous devez spécifier le codage du contenu pour qu'IIS 7 compresse les réponses application/json provenant d'ASP.NET MVC. En disant application/json n'est pas suffisante, elle doit être application/json; charset=utf-8 .

0 votes

NTOE : si applicationHost.config Il me semble que vous êtes probablement sur une machine 64 bits utilisant un éditeur 32 bits. Essayez notepad APRÈS AVOIR FAIT UNE SAUVEGARDE bien sûr. west-wind.com/weblog/posts/2008/Aug/09/

14voto

Ryan Kirkman Points 990

Utilisez ce guide

Aucune de ces réponses n'a fonctionné pour moi. J'ai pris note de la application/json ; charset=utf-8 de type mime cependant.

1 votes

+1 : cela a fonctionné pour moi, en utilisant le application/json; charset=utf-8 mime-type :o)

0 votes

Cela fonctionne pour moi, mais vous devez vous rappeler de redémarrer le SERVEUR et pas seulement le site web. par exemple, après avoir démarré inetmgr cliquez sur le nom de votre serveur et allez directement dans la rubrique Manage Server utilisez ce redémarrage et non le redémarrage individuel du site web.

7voto

takepara Points 5965

Je recommande cette approche
Créer CompressAttribute et définir l'action cible.

1 votes

Seulement quand tout le reste échoue ? IIS7+ ne devrait-il pas faire un meilleur travail ?

1 votes

C'est une bonne solution car vous pouvez mettre en cache et compresser, alors que IIS ne met en cache ou ne compresse que les données.

1 votes

C'est également une approche intéressante dans la mesure où la compression de petits messages peut coûter plus cher en compression/décompression qu'en transmission classique des données. La configuration de gzip pour tous les téléchargements JSON d'une application peut en fait faire perdre du temps pour ces petits messages, de sorte que la décoration des seuls téléchargements importants présente des avantages.

2voto

seagulledge Points 144

L'approche de l'attribut ActionFilterAttribute a été mise à jour pour ASP.NET 4.x et comprend le paquet Brotli.NET.

using System;
using System.IO.Compression;
using Brotli;
using System.Web;
using System.Web.Mvc;

public class CompressFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        HttpRequestBase request = filterContext.HttpContext.Request;

        string acceptEncoding = request.Headers["Accept-Encoding"];
        if (string.IsNullOrEmpty(acceptEncoding)) return;

        acceptEncoding = acceptEncoding.ToUpperInvariant();
        HttpResponseBase response = filterContext.HttpContext.Response;

        if (acceptEncoding.Contains("BR"))
        {
            response.AppendHeader("Content-encoding", "br");
            response.Filter = new BrotliStream(response.Filter, CompressionMode.Compress);
        }
        else if (acceptEncoding.Contains("GZIP"))
        {
            response.AppendHeader("Content-encoding", "gzip");
            response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
        }
        else if (acceptEncoding.Contains("DEFLATE"))
        {
            response.AppendHeader("Content-encoding", "deflate");
            response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
        }
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X