WSE, DIME; WCF, MTOM; OH My!

I was recently working on a proof of concept where we needed to interface to a repository that returned the documents using DIME attachments.  I don't know if you have had the 'opportunity' to work with DIME attachments before but there isn't much that still supports that format.  Since the manufacturer of the repository wasn't upgrading their software to take advantage of the new MTOM format we needed to consume the DIME attachments and convert them to MTOM attachments through an exposed WCF end point.

 

My client was putting this service on their ESB, which was built using BizTalk, and we utilized the WSE 2.0 extensions (yes, you can still download them) for the DIME support.

 

To do this we downloaded the WSE extensions and created a class that we would call from within our Orchestration.  We added a Web Reference to point to the web service of the repository.  We then replaced the default inherited class in the proxy with the WSE class, Microsoft.Web.Services2.WebServicesClientProtocol.  At this point we were ready to start writing code to consume the attachments.

In the code below, we loop through the attachments in the ResponseSoapContext and then load them into a stream object.  We then used the Convert class to convert the byte array to the properly converted Base64String and placed that as the value of the Attachment node.  The schema node's data type in the schema in BizTalk for the attachment is set to Base64Binary.  The best part about this whole POC is that by putting our attachment in the Base64Binary data type, all that we need to do is set the encoding on the WCF adapter to MTOM and BizTalk will do all the MTOM work for us.  Also in the code below, you will notice that we used Linq to XML.  The great part of POC's is that you can play with the new technology and in this case see just how easy it is to put together the XML message.  Even though we were playing with Linq, I still needed to pass back an XML Document for the Orchestration to consume.

 

using System;
using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Drawing;

using System.Xml.Linq;

using Microsoft.Web.Services2.Dime;

using System.IO;
using System.Xml.Serialization;

using System.Xml;

namespace OrchestrationHelper
{
[Serializable]
public class OrchestrationHelperWrapper
{

MyService.Service svc = new MyService.Service();

public XmlDocument RetrieveAttachment(int token, string name)

{

XElement xmlTree = null;

int iResult = svc.RetrieveFile(token, name);
XElement myNode;

if (iResult == 0) //0 = successful retrieve
                {
                    if (svc.ResponseSoapContext.Attachments.Count > 0)
                    {
                        XNamespace ns = "https://POC.DimeReturnSchema";
                        xmlTree = new XElement(ns + "ReturnedAttachments");
                        XElement xmlAttachments = new XElement("Attachments");
                        xmlTree.Add(xmlAttachments);
                        for (int index = 0; index < svc.ResponseSoapContext.Attachments.Count; index++)
                        {
                            Stream myStream = svc.ResponseSoapContext.Attachments[index].Stream;
                            int length = (int)myStream.Length;
                            
                            byte[] bytes = new byte[length];
                            myStream.Read(bytes, 0, length);

                            myNode = new XElement("Attachment", Convert.ToBase64String(bytes));
                            xmlAttachments.Add(myNode);
                        }
                    }
                }

                XmlDocument xdoc = new XmlDocument();
                xdoc.LoadXml(xmlTree.ToString());

                return xdoc;
        }
    }
}

Back in BizTalk, in our Orchestration, we called the OrchestrationHelper through the ConstructMessage shape and assigned the returned Xml Document to the Orchestration Message.  We created a WCF endpoint and selected Mtom encoding on the Binding tab of the WCF Transport Properties dialog.

 

The best part is that BizTalk automatically encoded anything that was set to Base64Binary to the MTOM format and it can all be done through configuration in the WCF adapter settings.  All that we needed to do was to consume the DIME attachment and place it in an element with the right data type.