I get this question relatively frequently:

“I need to send binary data in my SOAP message. What is the recommended way of doing this?”

(I’ll admit that I’m a bit late to the party on this one. Most of the information below is summarized from the referenced sources near the end of this post.)

You can always Base-64 encode the binary data, but this has a number of undesirable consequences including the encoding/decoding costs at the endpoints and a 33% size bloat on the wire. It does have the advantage that all the WS-* specs work with it.

So the next obvious question is how can I send the binary data as binary? This leads us to SOAP attachments. Unfortunately the SOAP attachments space is somewhat fragmented at the moment. The current options are:

  • SwA (SOAP with Attachments)
  • DIME (Direct Internet Message Encapsulation) (AKA WS-Attachments)
  • PASwA (Proposed Infoset Addendum to SOAP Messages with Attachments)
  • MTOM (Message Transmission Optimisation Mechanism)

All of these techniques send the attachments using MIME or a MIME-like mechanism. DIME adds record lengths to MIME for quick lookup of binary data. Unfortunately with SwA and DIME, the attachments are not part of the XML InfoSet, which means that you cannot apply the WS-* specs to them. (Probably most notable and serious is WS-Security. Using SwA or DIME, you can sign and/or encrypt parts of the SOAP message, but you cannot sign or encrypt the attachments. You can make guarentees that the message has not been tampered with, but you cannot make those same guarentees about the attachments.)

PASwA and MTOM solve this problem using an include element to incorporate the attachment into the XML Infoset. There seems to be general agreement that the way forward is MTOM. MTOM will be available with WSE 3.0 and Indigo. (WSE 3.0 is currently available as a CTP and Indigo is a Beta1 RC.)

So what should I do in the meantime? If you’re dealing with relatively few small binary attachments, Base-64 encoding seems to be the way to go. The extra 33% size and encoding/decoding costs probably won’t matter much to you.* On the plus side, you get to use all those snazzy WS-* specs. If you’re processing large numbers of messages and/or your attachments are large, the extra 33% size and encoding/decoding costs probably matter to you.* So you’ll have to use WSE 2.0 and DIME or roll your own SwA implementation (as Microsoft does not have an implemenation of SwA). Be aware that any WS-* goo that you apply will not work on the attachments. So don’t go sending images of bank statements via SwA or DIME!

* As with all things perf-related, measure, measure, measure. Don’t assume that Base-64 encoding is too slow for your situation and write a pile of extra encryption code for DIME attachments. Establish some performance criteria and measure against it. Then make an educated decision as to the solution architecture.

Here are some background articles that were good reads on the topic:

And don’t forget to catch John Bristowe‘s GrokTalk on MTOM in WSE 3.0:

Edit: Corrected wonky links and strange HTML formatting.