Sometimes there is a requirement to reduce the size of the messages sent between client and service. Encoder is a WCF component which transforms a SOAP message (Infoset) into a byte stream and vice versa. Kenny has written about the different encoders available in WCF and I highly recommend reading his post.

His post is focused on the performance characteristics of various encoders for various types of messages (with or without binary data).  Here I will talk about other aspect of the encoders. i.e size of the encoded byte stream.

Usually there are few requirements which derive your message size optimization options.

  1. Whether you own both side of communication (client & service) or not?
  2.  Do you require XML(Infoset) representation on the wire?
  3. Deployment options

 Let’s talk about various options in the light of above requirements.

If you own both sides then the recommendation is to use binary encoding which is the default encoding with NetTcpBinding & NetNamedPipeBinding. The XML structure on the wire will not preserved with this encoding however you will get huge savings in message size without writing any additional code.

If byte stream produced by binary encoding still doesn’t meet your bandwidth constraint then you can think of applying compression on this byte stream. There is a compression encoder available as part of WCF samples which you can use as a base to write your own compression encoder. Again this is only useful if wire format is not important to you. 

If you have a scenario in which message flows through intermediaries (e.g IBM DataPower) and certain policies are applied on the message (based on SOAP headers) then above options will not work. In these scenarios you can devise a scheme to only compress SOAP body and replace the actual body with compressed string (quite similar to XML encryption & Digital Signature) while preserving SOAP headers. Pablo has created a protocol (WS-Compression) to achieve this exact requirement. His sample is not updated to the latest version of WCF but you can get the idea by looking at the code. Also you can achieve this same functionality by extending WCF service model layer. For example, by writing a message inspector and doing compression there. 

I did a quick test of various encoding and compression choices and here are my findings. In my tests I have used a large dataset, consisting of 91 customer records, each having 1-20 orders and each order consist of 5-10 products.  

cid:image002.png@01C8D13A.DE114040

Encoding

Size

Bytes

Kb

Standard Text Encoding

1318179

1288

Standard Binary Encoding

259141

253

Gzip Compression using the compressing encoder        

131242

128

Gzip Compression using a custom compression channel

103428

101

 

 

 

 

 

As you can see there is huge size difference between text and binary encoding of xml messages. Note that in my testing there wasn’t any binary data in SOAP messages at all. If there would be some binary data then text encoded messages would be even bigger because of base64 encoding of binary data. So with binary encoding you can save lot of bandwidth without doing any custom coding and that’s why this should be the first choice.

In addition to using a compression encoder you can also use IIS compression if you are hosting in IIS or WPAS (Windows Server 2008). IIS compression is pretty much similar to compression encoder option with the only different that in the former case compression is done by IIS while in later case it is done by a WCF encoder. IIS compression has the disadvantage that you need to configure compression separate to your WCF configuration (IIS metabase).  Using a compression encoder or a custom compression channel also enables you to use a compression algorithm of your choice (based on your compression requirement) while IIS limits you to GZip compression only. In conclusion, the need for xml structure on the wire will be the deciding factor on what option will best suit you.