Click here to Skip to main content
Licence CPOL
First Posted 18 May 2011
Views 6,349
Downloads 63
Bookmarked 6 times

WCF does not support compression out of the box, so fix it

By | 18 May 2011 | Technical Blog
How to make compression work for WCF services.
A Technical Blog article. View original blog here.[^]

WCF services and clients do not support HTTP compression out of the box in .NET 3.5 even if you turn on Dynamic Compression in IIS 6 or 7. It has been fixed in .NET 4 but those who are stuck with .NET 3.5 for the foreseeable future, you are out of luck. First of all, it’s IIS' fault that it does not enable HTTP compression for SOAP messages even if you turn on Dynamic Compression in IIS 7. Secondly, it’s WCF’s fault that it does not send the Accept-Encoding: gzip, deflate header in HTTP requests to the server, which tells IIS that the client supports compression. Thirdly, it’s again WCF's fault that even if you make IIS to send back a compressed response, WCF can’t process it since it does not know how to decompress it. So, you have to tweak IIS and System.Net factories to make compression work for WCF services. Compression is key for performance since it can dramatically reduce the data transfer from the server to the client and thus give significant performance improvement if you are exchanging medium to large data over a WAN or the internet.

There are two steps – first, configure IIS, then configure System.Net. There’s no need to tweak anything in WCF like using some Message Interceptor to inject HTTP Headers, as you find people trying to do here, here, and here.

Configure IIS to support gzip on SOAP responses

After you have enabled Dynamic Compression on IIS 7 following the guide, you need to add the following block in the <dynamicTypes> section of the applicationHost.config file inside the C:\Windows\System32\inetsrv\config folder. Be very careful about the spaces in mimeType. They need to be exactly the same as you find in the response header of the SOAP response generated by WCF services.

<add mimeType="application/soap+xml" enabled="true" />
<add mimeType="application/soap+xml; charset=utf-8" enabled="true" />
<add mimeType="application/soap+xml; charset=ISO-8895-1" enabled="true" />

After adding the block, the config file will look like this:

image

For IIS 6, you need to first enable dynamic compression and then allow the .svc extension so that IIS compresses responses from WCF services.

Next, you need to make WCF send the Accept-Encoding: gzip, deflate header as part of the request, and then support decompressing a compressed response.

Send proper request header in WCF requests

You need to override the System.Net default WebRequest creator to create a HttpWebRequest with compression turned on. First, you create a class like this:

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

Then on the WCF client application’s app.config or web.config, you need to put this block inside system.net which tells system.net to use your factory instead of the default one.

<system.net>
  <webRequestModules>
    <remove prefix="http:"/>
    <add prefix="http:"
      type="WcfHttpCompressionEnabler.CompressibleHttpRequestCreator, 
            WcfHttpCompressionEnabler, Version=1.0.0.0, 
            Culture=neutral, PublicKeyToken=null" />
  </webRequestModules>
</system.net>

That’s it.

I have uploaded a sample project which shows how all these works.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Omar Al Zabir

Architect
BT, UK (ex British Telecom)
United Kingdom United Kingdom

Member

I am: Chief Architect, SaaS Platform, BT (ex British Telecom). Visual C# MVP '05-'07, ASP.NET/IIS MVP '08-'12
I was: Co-founder & CTO, Pageflakes(www.pageflakes.com)
I like: Performance and Scalability Challenges.
My Book: Building a Web 2.0 portal using ASP.NET 3.5. Also on Amazon
My Blog: http://omaralzabir.com
My Specialization: Web 2.0 Rich AJAX Applications, Level 4 SaaS, Performance and Scalability of Web Apps.
My Email: OmarALZabir at gmail dot com
 
Follow Me: twitter.com/omaralzabir
 
My Projects:
Open Source Web 2.0 AJAX Portal
PlantUML Editor - Super fast UML editor
Smart UML - Freehand UML Designer
RSS Aggregator both Outlook and Standalone
Store Front in JSP but ASP.NET style
 
My Articles:
Top 10 caching mistakes
99.99% Available Production Architecture
Build GoogleIG like Ajax Start Page in 7 days
10 ASP.NET Performance and Scalability Secrets
ASP.NET AJAX under the hood secrets
UFrame: UpdatePanel and IFRAME combined
Fast ASP.NET web page loading
Fast Streaming AJAX Proxy
Using COM safely inside "using" block without requiring interop assembly
Implementing Word Like Automation Model
Distributed Command Pattern

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
-- There are no messages in this forum --
Permalink | Advertise | Privacy | Mobile
Web04 | 2.5.120517.1 | Last Updated 18 May 2011
Article Copyright 2011 by Omar Al Zabir
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid