WCF la Compression GZip de Demande/Réponse de Traitement

Comment puis-je obtenir un WCF client traiter les réponses du serveur qui ont été Gzippé ou Dégonflé par IIS?

Sur IIS, j'ai suivi les instructions ici sur la façon de faire IIS 6 gzip toutes les réponses (d'où la demande contenait des "Accept-Encoding: gzip, deflate") émis par la .svc services wcf.

Sur le client, j'ai suivi les instructions ici et ici sur la façon d'injecter cet en-tête dans le web demande: "Accept-Encoding: gzip, deflate".

Fiddler2 montre la réponse est binaire et non pas de simples données Xml.

Le client se bloque avec une exception qui dit en gros il n'y a pas d'en-tête Xml, ce qui bien sûr est vrai.

Dans mon IClientMessageInspector, l'application se bloque avant AfterReceiveReply est appelé.

Quelques précisions supplémentaires:

(1) je ne peux pas modifier le service ou client WCF comme ils sont fournis par une 3ème partie. Je peux toutefois associer des comportements et/ou message d'inspecteurs, via la configuration, si c'est la bonne direction à prendre.

(2) je ne veux pas compresser/décompresser juste le savon corps, mais l'intégralité du message.

Toutes les idées/solutions?

* RÉSOLU *

Il n'était pas possible d'écrire un WCF extension pour atteindre ces objectifs. Au lieu de cela j'ai suivi ce CodeProject l'article qui prônent une classe helper:

public class CompressibleHttpRequestCreator : IWebRequestCreate
{
    public CompressibleHttpRequestCreator()
    {
    }

    WebRequest IWebRequestCreate.Create(Uri uri)
    {
        HttpWebRequest httpWebRequest = 
            Activator.CreateInstance(typeof(HttpWebRequest),
            BindingFlags.CreateInstance | BindingFlags.Public | 
            BindingFlags.NonPublic | BindingFlags.Instance,
            null, new object[] { uri, null }, null) as HttpWebRequest;

        if (httpWebRequest == null)
        {
            return null;
        }

        httpWebRequest.AutomaticDecompression =DecompressionMethods.GZip | 
            DecompressionMethods.Deflate;

        return httpWebRequest;
    }
} 

et aussi, un ajout au fichier de configuration d'application:

<configuration>
  <system.net>
    <webRequestModules>
      <remove prefix="http:"/>
      <add prefix="http:" 
            type="Pajocomo.Net.CompressibleHttpRequestCreator, Pajocomo" />
    </webRequestModules>
  </system.net>
</configuration>

Ce qui semble se passer, c'est que WCF, éventuellement, demande à certains de l'usine ou de l'autre au plus profond de system.net pour fournir une HttpWebRequest exemple, et nous offrons de l'aide qui sera demandé de créer l'instance.

Dans la WCF fichier de configuration du client, une simple basicHttpBinding est tout ce qui est nécessaire, sans la nécessité pour toutes les extensions personnalisées.

Lorsque l'application s'exécute, le client requête Http contient l'en-tête "Accept-Encoding: gzip, deflate", le serveur renvoie un format de réponse web, et le client de manière transparente décompresse la réponse http, avant de le remettre à la WCF.

Quand j'ai essayé d'appliquer cette technique à des Services Web, j'ai trouvé qu'il ne fonctionne PAS. Bien que la classe helper a été exécuté de la même façon que lorsqu'il est utilisé par la WCF client, la requête http ne contient pas les "Accept-Encoding: ..." en-tête.

Pour faire ce travail pour les Services Web, j'ai dû modifier la classe Proxy Web, et ajouter cette méthode:

protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
    System.Net.HttpWebRequest rq = (System.Net.HttpWebRequest)base.GetWebRequest(uri);
    rq.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
    return rq;
}

Noter qu'il n'a pas d'importance si le CompressibleHttpRequestCreator et de bloc à partir du fichier de config étaient présents ou non. Pour les services web, seulement primordial GetWebRequest dans le Service Web Proxy travaillé.

  • Pourquoi ne pas poster votre solution comme une réponse au lieu de la partie de la question, de sorte que vous pouvez l'accepter?
  • Que voulez-vous dire par: "Pour faire ce travail pour les Services Web, j'ai dû modifier la classe Proxy Web, et ajouter cette méthode:"? qu'est-ce que la classe proxy web??
InformationsquelleAutor IanT8 | 2009-11-16