WsReplix: SOAP with Attachments between Java and .Net based Web Services Introduction: What does WsReplix solve? WsReplix stands for Web Service based Replication, and is a toolkit/ starting point for implementing Web Service solutions that involves replication of files over HTTP based on Web Services, supporting both Java and .Net plattforms. The service endpoint controls from which directory the client can receive files, an the client controls where to store the retrieved files. The Web Service client asks the service for information about which files recides currently on the service side, including the size and last modified date for each file, and then requests the service for which files it wants to get a copy of. The service attaches the requested files to the SOAP message response, and the client saves the files. SOAP implementations used For Java Sun's Java Web Services Developer Pack 1.3 (JWSDP 1.3) was used, and for .Net the .Net framework 1.1. The .Net solutions where written in C# Libraries For Base64 encoding/decoding in Java, a Public Domain library written by Robert Harder was used, see http://iharder.net/xmlizable and comments in the source file Base64.java Technical solution The main challenge here is to attach binary files to SOAP messages, in a manner that interoperates between the Java and the .Net plattforms. This could be solved in several different ways, of which we have chosen to implement two different solutions in WsReplix. Simple solution: Base-64 encoded data As discussed in [1], the simplest solution is to encode the binary data in a string and send it over the wire inside the SOAP message. Quote: "This works across all possible transports, is known to interoperate well across all implementations, and is pretty much guaranteed to work with small amounts of data. Yet base-64 has its limits. Its inefficient, using only 6 bits of each byte, it adds about a third to the length of a message, plus perhaps a bit of padding to set the length. Note that there is a proposed base-85 encoding which uses less space, but is not integrated with any SOAP libraries. When sending large files, the issue becomes not just the expansion of the payload, but the actual process for encoding it and sending it over the wire. A 2KB file is easy to encode and ship; a 3MB file consumes memory while it is encoded and takes 4MB worth of uplink channel. It then causes no end of havoc at the far end, depending upon the XML parser. XML parsers are not usually engineered to have strings that large inside them. A 200MB file, or a 1GB file doesn’t bear thinking about." SwA: Soap with Attachments Soap with Attachments extends the existing MIME standard to cover sending a SOAP message as the first attachment in a set of attachments sent to a Web Service endpoint. Unfortunately, .Net does not support this format (they support DIME instead), but by using a SOAPExtension handler it is possible to grab and handle the attachments in a .Net Web Service endpoint as well. What's next? Limitations There's of course a lot of limitations in this package, whatever you call it (a toolkit, a prototype or whatever). There's of course no deal to have hardcoded the directory names for where to get/put the attached files, and the .Net client in the nature of a Web application which retrieves files when you hit a button is probably not how you would have done this in a production system etc. The .Net service do only support file attachments as encoded content inside the Soap message, and not as MIME multipart attachments, thus retrieving large files from the .Net-service is supposed to give the parsers a heavy load. Layout of MIME multi-part message The logic in the .Net SOAP Extension (SOAPEx_ReceiveMIME.cs) assumes for the SOAP response that: the Content-ID header occurs right before the encoded content the soap envelope starts with "<env:Envelope" and ends with "</env:Envelope>" the filelist in the soap body lists each filename (which again should correspond to the content-ID) preceded with <item xsi:type="xsd:string"> Todo list If one intend to use the WsRepix package to something more than just to play with Soap attachments, here's a list of some things to look closer at: Configurable get/put directories (using a property file or whatever) Configurable rules of which files to retrieve (based on file names, size, extentions etc.), considerable on both client and service side Tips & Tricks Add a Web Reference in .Net :8080 in Web.config Refresh a Web Reference in .Net "405 Method not allow": Rebuild all Bonus: How to send a SOAP header from .Net Though not used in this solution, we have succeeded in sending a SOAP Header from .Net to a Java based service. This was done the following way: We did not find any way to get a SOAP header to be automatically described in the genereated WSDL file in the Java service, so we had to do the header declaration etc. manually in .Net. This was done by adding the following code to the generated proxy (Reference.cs) in .Net: 1. Declare the SOAP header as a separate class inside the same namespace as the service class: [System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:Foo")] [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:Foo", IsNullable=false)] public class UserAuthInfo : SoapHeader { public int headerID; } 2. Declare a class variable inside the service class: public UserAuthInfo UserAuthInfoValue; 3. Decorate the service method(s) for which the SOAP header should be sent: [System.Web.Services.Protocols.SoapHeaderAttribute("UserAuthInfoValue ", Required=false)] 4. In the client code, create an instance of the SOAP header class, and assign it to the service class variable (declared in step 2 above): UserAuthInfo oAut= new UserAuthInfo(); oAut.headerID = 100; ws.UserAuthInfoValue = oAut; // ws is the web service instance References and links [1] "Fear of Attachments" Steve Loughran 2003-02-03. http://www.mailarchive.com/axis-user@xml.apache.org/msg08732/Fear_of_Attachments.pdf [2] http://msdn.microsoft.com/msdnmag/issues/04/03/ASPColumn/default.aspx