<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://bloggingabout.net/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Search results matching tags 'WCF', 'Silverlight', 'fiddler', 'gzip', and 'HttpCompression'</title><link>http://bloggingabout.net/search/SearchResults.aspx?a=1&amp;o=DateDescending&amp;tag=WCF,Silverlight,fiddler,gzip,HttpCompression&amp;orTags=0</link><description>Search results matching tags 'WCF', 'Silverlight', 'fiddler', 'gzip', and 'HttpCompression'</description><dc:language>en-US</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>WCF and http (gzip/deflate) compression and Silverlight</title><link>http://bloggingabout.net/blogs/ramon/archive/2008/11/06/wcf-and-http-gzip-deflate-compression-and-silverlight.aspx</link><pubDate>Thu, 06 Nov 2008 10:11:18 GMT</pubDate><guid isPermaLink="false">813b6dfd-644e-4573-a816-eebab56ba0d0:476568</guid><dc:creator>Ramon Smits</dc:creator><description>&lt;p&gt;The last couple of days I&amp;#39;ve tried to see if it was possible to make use of standard http compression on WCF services as I had very good experiences with WSE and even asmx webservices that used http compression to save bandwidth - but more important - and have better response times for large xml messages.&lt;/p&gt;&lt;!--more--&gt; &lt;h2&gt;Tracing request/response with Fiddler&lt;/h2&gt; &lt;p&gt;I created a small test project containing a contract and both a client and a service based on that contract and launched fiddler. I discovered that WCF does NOT add the &lt;strong&gt;Accept-Encoding:&lt;/strong&gt; header with &lt;strong&gt;gzip&lt;/strong&gt; and/or &lt;strong&gt;deflate&lt;/strong&gt; values. So I fired the request again from fiddler but now I manually entered the Accept-Encoding header and the result was not compressed so I needed to first enable http compression in IIS.&lt;/p&gt; &lt;h2&gt;Enable IIS http compression for WCF services&lt;/h2&gt; &lt;p&gt;To enable http compression in IIS (6) you need to do the following:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Launch the IIS mmc snapin&lt;/li&gt; &lt;li&gt;Select the properties of &lt;strong&gt;Web sites&lt;/strong&gt;&lt;/li&gt; &lt;li&gt;Go to the &lt;strong&gt;Service&lt;/strong&gt; tab&lt;/li&gt; &lt;li&gt;Enable &lt;strong&gt;Compression application files&lt;/strong&gt;&lt;/li&gt; &lt;li&gt;Select &lt;strong&gt;OK&lt;/strong&gt;&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;This enables http compression for dynamic content but now we need to let IIS know which dynamic content to compress. I will do this with the commandline &lt;strong&gt;adsutil.vbs&lt;/strong&gt; script. Here I add http compression for &lt;strong&gt;.svc&lt;/strong&gt; files and also change the default compression level from 0 to 9.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;CSCRIPT.EXE ADSUTIL.VBS SET W3Svc/Filters/Compression/GZIP/HcScriptFileExtensions &amp;quot;asp&amp;quot; &amp;quot;dll&amp;quot; &amp;quot;exe&amp;quot; &amp;quot;svc&amp;quot;&lt;br /&gt;CSCRIPT.EXE ADSUTIL.VBS SET W3Svc/Filters/Compression/DEFLATE/HcScriptFileExtensions &amp;quot;asp&amp;quot; &amp;quot;dll&amp;quot; &amp;quot;exe&amp;quot; &amp;quot;svc&amp;quot;&lt;br /&gt;CSCRIPT.EXE ADSUTIL.VBS SET W3Svc/Filters/Compression/GZIP/HcDynamicCompressionLevel 9&lt;br /&gt;CSCRIPT.EXE ADSUTIL.VBS SET W3Svc/Filters/Compression/DEFLATE/HcDynamicCompressionLevel 9 &lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;After changing these settings you will need to restart IIS by launching &lt;strong&gt;iisreset&lt;/strong&gt;. &lt;h2&gt;Add Accept-Encoding http header to request&lt;/h2&gt; &lt;p&gt;Here we have two possibilities. The first is the easiest by just adding the property to the operation context as shown below.&lt;/p&gt;&lt;span class="Apple-style-span" style="word-spacing:0px;font:12px consolas;text-transform:none;text-indent:0px;white-space:normal;letter-spacing:normal;border-collapse:separate;orphans:2;widows:2;-webkit-border-horizontal-spacing:0px;-webkit-border-vertical-spacing:0px;-webkit-text-decorations-in-effect:none;-webkit-text-size-adjust:auto;-webkit-text-stroke-width:0;"&gt;&lt;pre style="font-size:small;margin:0em;color:black;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; (&lt;span class="kwrd"&gt;new&lt;/span&gt; OperationContextScope(client.InnerChannel))&lt;/pre&gt;&lt;pre style="font-size:small;margin:0em;color:black;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;"&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;&lt;pre style="font-size:small;margin:0em;color:black;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    var properties = &lt;span class="kwrd"&gt;new&lt;/span&gt; HttpRequestMessageProperty();&lt;/pre&gt;&lt;pre style="font-size:small;margin:0em;color:black;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;"&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    properties.Headers.Add(HttpRequestHeader.AcceptEncoding, &lt;span class="str"&gt;&amp;quot;gzip,deflate&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="font-size:small;margin:0em;color:black;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    &lt;span class="rem"&gt;//... call here&lt;/span&gt;&lt;/pre&gt;&lt;pre style="font-size:small;margin:0em;color:black;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;"&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;}&lt;/pre&gt;&lt;/span&gt;
&lt;p&gt;The second option is creating a client message inspector by inheriting from IClientMessageInspector and configure WCF to use the message inspector for a certain end-point. The message inspector would do exactly the same as the code above but then within the WCF pipeline. I will leave that as nice exercise ;-)&lt;/p&gt;
&lt;h2&gt;WCF client &lt;/h2&gt;
&lt;p&gt;I launched my client and there I saw that the Accept-Encoding header was set in the request and that the result now got compressed by IIS but there WCF failed to decompress the result automatically so I started searching for a &lt;b&gt;EnableDecompression&lt;/b&gt; like setting that web references have on the WCF client proxy and other WCF pipeline related settings but could not find a way to let WCF decompress the gzip/deflate response. The WCF technology samples contain a compression example and I modified it a bit. It uses &lt;strong&gt;gzip&lt;/strong&gt; but that did not seem to work in fiddler so I used &lt;strong&gt;deflate&lt;/strong&gt; in the example code and that worked and I also changed the code &lt;u&gt;to NOT alter the content-type&lt;/u&gt;. Here I learned that you &lt;u&gt;&lt;strong&gt;cannot&lt;/strong&gt; change the transport properties in a &lt;strong&gt;MessageEncoder&lt;/strong&gt;&lt;/u&gt;&lt;strong&gt;. &lt;/strong&gt;But this is only needed when you want to compress your request or compress your response if you do not want IIS to do it for you (because you don&amp;#39;t use IIS). So I used a message inspector implementing IClientMessageInspector and IDispatchMessageInspector to automatically set the AcceptEncoding and ContentEncoding http headers. This was working perfectly but I could not achieve to decompress the response on the server by first detecting the &amp;quot;ContentEncoding&amp;quot; header thus I used the work around to first try to decompress it and if it fails just try to process the request as normal. I also did this in the client pipeline and this also works.&lt;/p&gt;
&lt;h2&gt;Silverlight magic&lt;/h2&gt;
&lt;p&gt;I then tried to see the behavior of Silverlight as it delegates the http request to the browser to do the actual call and there I noticed that http compression works perfectly with Silverlight on a service reference. So the browser probably decompressed the response before Silverlight will get the data stream. Which accidentally is perfect for the scenarios in which we want to make use of http compression.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I now ditched this as we also need to support clients that do not set the AcceptEncoding header so I really need the ability to read the http header in request and set a &amp;quot;context&amp;quot; value to (not) compress the response and I have not found out yet how to do that per multiple concurrent requests. &lt;u&gt;I really recommend to use the IIS http compression and not try to do this with WCF hacking as described here!&lt;/u&gt; If you want to compress your request than this is probably the only way to achieve this in the current WCF version.&lt;/p&gt;
&lt;p&gt;If you want to make use of http compression in .net clients to decompress the response then just use a web reference instead of a service reference and make use of the &lt;b&gt;EnableDecompression&lt;/b&gt; setting except when you use Silverlight as the client.&lt;/p&gt;</description></item></channel></rss>