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 = “http://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.

ESB Toolkit How To Video #5: Including Custom Orchestrations in Itineraries

Update: Sorry folks, the first link I posted for the video was incorrect. I have updated it now:

Welcome to #5 in my series of ESB Toolkit How To Videos. If you have not seen the previous videos, I encourage you to do so. The previous ones can be found here

1) Basic Itinerary Routing and UDDI Integration

2) Composite Itinerary and Dynamic Mapping

3) Itinerary Resolution in the Bus

4) Dynamic Itinerary Resolution in the Bus

One of the great things about the ESB Toolkit is that it can be extended in a large number of ways. One of the common ways that developers will want to extend it, is to create custom BizTalk orchestrations that can be included within an ESB itinerary. With the default install of the Toolkit, you have access to two orchestration. The generic routing orch and the generic mapping orch. In this video, I’ll show you how to create a new orchestration and then register it with the ESB so that you can access it from the itinerary designer and create an itinerary that will route messages to it.

The video can be accessed here

Cheers and keep on BizTalking…

Peter

Litware Training sample Mashup app

We’ve all heard of a "mashup" because its one of those buzz words, like "Web 2.0", that is picked up and repeated over and over again by the journalists and analysts.  But have you actually seen one up close in the wild?  Or do you have suspicions that its an elusive beast or a myth like Big Foot or Nessie?  Well, we’ve got one of these critters in captivity for you to take home as a pet.  Play with it.  Get comfortable.  See what makes it tick.  See what tools from Microsoft are useful in building a mashup. And see if this programming style applies to something you want to do with your next application.

Litware Training is a sample "mashup" app built using ASP.NET and the WCF REST Starter Kit Preview 2. It demonstrates how to build a Web 2.0 application, tapping into popular search, geographic information, and social networking APIs on the internet. It shows how to consume and expose RESTful services.

Thanks to Ben Dewey of twentysix New York who built the sample.

BizUnit 3.1

BizUnit 3.1

BizUnit 3.1 is now released. (Actually its been out for over a week). There are a few bug fixes in this release and most notable is the addition of the following steps that Bram Veldhoen contributed.

BizTalkSteps/ExecuteMapStep
BizTalkSteps/ExecuteReceivePipelineStep
BizTalkSteps/ExecuteSendPipelineStep

The Pipeline steps use Tomas Restrepo’s Pipeline Testing Library.
I had originally planned on incorporating Bram’s steps into Extensions as I […]

EDI/AS2 in BizTalk 2009 : How to get the BatchId for a specific BatchName

One of the new features in BizTalk 2009 EDI is the possibility to create multiple batch configurations for each party.
Each batch will have a specific name and specific batchID and can be managed individually.


For a specific batch name you can get the corresponding batch ID. For example you may need this for an external trigger message for that batch.


If you want to do that programmatically, you may expect you can just call Partner.GetBatchIdForBatchName method by passing the batch name.
http://msdn.microsoft.com/en-us/library/microsoft.biztalk.edi.partneragreementmanager.partner.getbatchidforbatchname.aspx


But looking at the signature of that method, it is probably not what you want. Instead of expecting just a string for the batch name, this method wants two int, the partyID and the messageType. But if you just want to pass in the batch name, you do not get very far with that method.


To get the batch ID for a batch name, we have a stored procedure you can call from code: edi_GetBatchIdForBatchName .
Calling 
  exec edi_GetBatchIdForBatchName ‘MyBatch’
will return the ID of the batch name MyBatch.



Note: both calling GetBatchIdForBatchName and edi_GetBatchIdForBatchName directly is not supported.


 


Manuel Stern