Out of the box Silverlight provides two message encoding types for sending SOAP messages over the wire. These are TextEncoding and BinaryEncoding. MTOM encoding is still not available within Silverlight.
Binary encoded messages produce a payload that is about half the size of a message encoded with standard text encoding. Please note that binary encoding is a Microsoft proprietary implementation and therefore not interoperable outside the .NET framework.
In our Silverlight applications we use a .NET to .NET messaging scenario (like many other SL apps too), which means Silverlight communicates with a WCF backend. Using then binary encoded messages is obvious.
You will find a lot of blog posts out there in the community when you are interested in binary vs. text-encoding comparison.
What exactly does BinaryEncoding?
When the encoding is set to binary, then the DataContractSerializer still produces SOAP messages as XML but after that the messages get transformed into a binary representation of the XML with help of the XmlDictionaryWriter class.
The following code snippet shows the usage of the XmlDictionaryWriter class (not WCF related).
You should not compare the XmlDictionaryWriter with the well-known BinaryFormatter in the mscorlib. The BinaryFormatter produces a binary representation of an object graph. The XmlDictionaryWriter on the other hand translates a textual XML into a binary representation. Serializing a XML string with the BinaryFormatter will not reduce the size, because the XML is just a single string from this point of view.
The textual output form the example above indicates that it is a kind of an optimized XML structure.
Optimize Data Contracts
Binary XML still includes the names of the elements and attributes as plain text.
When setting the name of my data contracts to a single character then the SOAP message size will be reduced by additional 30-50 percent (depends on the data structure).
The SOAP-Envelop then look like this:
Rules for setting the name:
- Each data contract must have a unique name in the scope of its namespace
- Each data member must have a unique name in the scope of its class.
- Use character [A-Za-z], you can mix upper and lower case.
After these changes the generated proxy on client side is quite unhandy, because the classes and members are named like they are declared in the contracts. Therefore I created a shared lib and reuse the data contracts on client side.
Assemblies built in Silverlight are in general not binary compatible with the .NET Framework, so if you want to share code you need to dual-compile your code. Since Silverlight 4 you will be able to use some Silverlight-based assemblies from within .NET 4. In order to load a Silverlight assembly in .NET, the assembly may only reference the following assemblies: mscorlib.dll, System, System.Core.dll, System.ComponentModel.Composition.dll, Microsoft.VisualBasic.dll.
Well, my shared data contracts dll needs a reference to System.Runtime.Serialization.dll which is currently not binary compatible with the Silverlight runtime.
Therefore I do a dual-compile by adding the same source file with “Add As Link” to my Silverlight library.
As final task I add a reference to SharedDataContract.SL assembly and update my service reference. Please check that the option “Reuse types in referenced assemblies” is checked.
Comparison of different configurations
Text encoding / standard contract
Text encoding / optimized contracts
Binary encoding / standard contracts
Binary encoding / optimized contracts
When communicating in a .NET to .NET messaging scenario then optimizing the data contracts is an additional way to reduce the SOAP message size. This together with binary encoding will reduce the message size about 4 times. Especially looking to the Windows Phone 7 development this will help when the traffic goes over a low bandwidth network.