I frequently hear comments that Web services are inappropriate for carrying large data messages, say greater than 1 MB.  In the past there was some truth to that, but no longer.  There is really no reason to avoid a Web service simply because you have to send or receive a bunch of data.

By default, transferring non-ASCII data over a SOAP call means using Base64 encoding.  You have to go back to the early days of the Internet to find the Base64 definition in IETF RFC 1521, which was adapted from an even earlier RFC.  Base64 typically increases the size of the encoded data by 33%, not to mention the CPU and memory required to encode and decode.  Imagine sending a 3 MB PDF over a SOAP call with Base64 encoding.  That PDF gets translated into a 4 MB ASCII string, transmitted to the other endpoint, and then converted back to the original 3 MB PDF.  Clearly this is not an efficient scheme.

Years ago, Microsoft first addressed this issue in the Web Services Enhancements (WSE) add-on to .NET with their proprietary DIME extension to SOAP.  Like MIME, DIME is designed to define message attachments of varying data types, but in this case to a SOAP message.  According to Microsoft, DIME was a more efficient format than MIME for message parsers.  It was not widely adopted.

Why attachments?  Just like sending an email, you might want to send a SOAP message that carries alongside it one or more other chunks of data, whether that’s a ZIP file, another XML file, a PDF, etc.  An attachment scheme like MIME defines in the message header the list of attachments, and for each attachment an encoding method.  We would prefer to use a binary encoding method that does not increase the size of our data.

The W3C standards organization got involved with the advent of the Message Transmission Optimization Mechanism (MTOM), which today is a W3C Recommendation.  MTOM uses concepts from MIME/Multipart to add attachments to a SOAP message, and it can optimize elements of type base64Binary.  If you put data into a base64Binary element with MTOM disabled, you will literally see a Base64-encoded version of your data (and much bigger than the original).  If you look at the same element with MTOM enabled, you will find a pointer to a MIME part that contains your actual data in binary format.

MTOM is available today for .NET 2.0 Web services in Web Services Enhancements (WSE) 3.0 and Windows Communication Foundation.  Both of these are freely available and fairly easy to use.  WSE 3.0 is perfect for your existing ASMX Web services because there is usually no code to change to take advantage of MTOM.  Keep in mind that clients of an MTOM Web service also need to be MTOM-aware.  The only requirement is that the data element you wish to optimize is of type base64Binary in the XML, and a byte array in your .NET code.  Once you enable WSE3 on your Web service project, you can simply enable MTOM in the WSE configuration.  Remember to enable it on the client side too.

Attached to this post you will find a sample .NET 2.0 solution that demonstrates a single Web service implemented in plain ASMX, ASMX with WSE3 and WCF.  You’ll notice that there is no special code at all for MTOM, just configuration.  If you use an HTTP monitor like Fiddler to examine the SOAP messages, you will see the differences with and without MTOM.

It is worth pointing out that BizTalk 2006 Web services CAN take advantage of MTOM!  When you publish a schema or orchestration as a Web service, what comes out is a regular old .NET 2.0 ASMX Web service.  Again, as long as the large data elements are defined as type base64Binary and as a byte array in code, MTOM can be enabled with no code changes.  Just update the BizTalk Web service project to enable WSE3 and MTOM.

Please contact me if you have questions, and please take advantage of these free and easy tools to make your Web services faster.

webservicesmtomdemo.zip