Wie bekomme ich einen WCF-Client zur Verarbeitung von Server-Antworten, die von IIS Gziped oder Deflated wurden?WCF GZip Compression Anfrage/Antwort Verarbeitung
Auf IIS, ich habe die Anweisungen here auf, wie IIS 6 Gzip alle Antworten (wo die Anfrage enthalten "Accept-Encoding: gzip, deflate") von .svc WCF-Dienste emittiert.
Auf dem Client habe ich die Anweisungen here und here auf, wie man diesen Header in die Web-Anfrage injizieren: "Accept-Encoding: gzip, deflate".
Fiddler2 zeigt die Antwort ist binär und nicht einfach alte Xml.
Der Client stürzt mit einer Ausnahme, die im Grunde sagt, es gibt keine Xml-Header, was natürlich wahr ist.
In meinem IClientMessageInspector stürzt die App ab, bevor AfterReceiveReply aufgerufen wird.
Einige weitere Hinweise:
(1) Ich kann den WCF-Dienst oder Client nicht ändern, da sie von einer dritten Partei geliefert werden. Ich kann jedoch Verhaltensweisen und/oder Nachrichteninspektoren über die Konfiguration hinzufügen, wenn dies die richtige Richtung ist.
(2) Ich möchte nicht nur den Seifenkörper komprimieren/dekomprimieren, sondern die gesamte Nachricht.
Irgendwelche Ideen/Lösungen?
* GELÖST *
Es war nicht möglich, eine WCF-Erweiterung zu schreiben, um diese Ziele zu erreichen. Stattdessen folgte ich diese Codeproject article, die eine Hilfsklasse vertreten:
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;
}
}
und auch eine Ergänzung der Anwendungskonfigurationsdatei:
<configuration>
<system.net>
<webRequestModules>
<remove prefix="http:"/>
<add prefix="http:"
type="Pajocomo.Net.CompressibleHttpRequestCreator, Pajocomo" />
</webRequestModules>
</system.net>
</configuration>
Was passiert zu sein scheint, ist, dass WCF schließlich eine Fabrik fragt oder tief in system.net, um eine HttpWebRequest-Instanz bereitzustellen, und wir stellen den Helper zur Verfügung, der aufgefordert wird, die erforderliche Instanz zu erstellen.
In der WCF-Clientkonfigurationsdatei ist lediglich ein einfaches basicHttpBinding erforderlich, ohne dass benutzerdefinierte Erweiterungen erforderlich sind.
Wenn die Anwendung ausgeführt wird, enthält die Client-HTTP-Anforderung den Header "Accept-Encoding: gzip, deflate", der Server gibt eine Webantwort mit gzip zurück und der Client dekomprimiert die HTTP-Antwort transparent, bevor sie an WCF übergeben wird.
Als ich versuchte, diese Technik auf Web Services anzuwenden, fand ich, dass es nicht funktionierte. Obwohl die Hilfsklasse im gleichen Zustand ausgeführt wurde, in der sie vom WCF-Client verwendet wurde, enthielt die HTTP-Anforderung nicht den Header "Accept-Encoding: ...".
Um diese Arbeit für Web Service zu machen, hatte ich die Web-Proxy-Klasse zu bearbeiten, und fügen Sie diese Methode:
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;
}
Beachten Sie, dass es nicht darum, ob war der CompressibleHttpRequestCreator und Block aus der Anwendung Konfigurationsdatei war egal Gegenwart oder nicht. Bei Webdiensten hat nur das Überschreiben von GetWebRequest im Web-Service-Proxy funktioniert.
Warum posten Sie Ihre Lösung nicht als Antwort, sondern als Teil der Frage, damit Sie sie akzeptieren können? –
Was bedeutet das? "Damit dies für Web Services funktioniert, musste ich die Web Proxy-Klasse bearbeiten und diese Methode hinzufügen:"? Was ist die Web-Proxy-Klasse? – Naor