Json, Send and Receive Pipelines for BizTalk Server.

Announcing the release of the Json pipelines for BizTalk Server, Rest (web-http) adapter was release in BT 2010 which opened up new playground for integration specialists, and we could boast of BizTalk server’s OOB support both Rest and Soap protocols, but the one thing that was still missing was Json support.

Here in the blog post I will discuss & demonstrate on how to add json support using custom pipeline components, the entire source code is available on GitHub including unit tests ,apart from BizTalk we need the ESB tool kit components installed (only the pipelines).

Scenario 1: We need to send out a Json Message to an external endpoint, one of the solution for this is to create a new PC and use the Newtonsoft Json libraries JsonConvert.SerializeObject method to convert the xml stream into an object and generate a json string, the following is the code and the pipeline implementation.

Xml to Json pipeline component (DotNetTypesToJsonConverter.cs)

Json send pipeline.

IBaseMessage IComponent.Execute(IPipelineContext pContext, IBaseMessage pInMsg)
{
Trace.WriteLine(“DotNetTypesToJsonConverter Pipeline – Entered Execute()”);
Trace.WriteLine(“DotNetTypesToJsonConverter Pipeline – TypeName is set to: ” + TypeName);
IBaseMessagePart bodyPart = pInMsg.BodyPart;
if (bodyPart != null)

{

Stream originalStream = bodyPart.GetOriginalDataStream();

if (originalStream != null)

{

Type myClassType = Type.GetType(TypeName);

object reqObj = PcHelper.FromXml(originalStream, myClassType);

string jsonText = JsonConvert.SerializeObject(reqObj, myClassType, Formatting.None,

new JsonSerializerSettings());

Trace.WriteLine(“DotNetTypesToJsonConverter output: ” + jsonText);

byte[] outBytes = Encoding.ASCII.GetBytes(jsonText);

var memStream = new MemoryStream();

memStream.Write(outBytes, 0, outBytes.Length);

memStream.Position = 0;

bodyPart.Data = memStream;

pContext.ResourceTracker.AddResource(memStream);

}

}

Trace.WriteLine(“DotNetTypesToJsonConverter Pipeline – Exited Execute()”);

return pInMsg;

}

Scenario 2: We need to receive a Json message from an external endpoint and convert it into Xml for BizTalk’s further processing, one of the solution for this is to create a new PC and use the Newtonsoft Json libraries , I used the idea from an existing blog post http://www.modhul.com/2013/04/30/restfully-getting-json-formatted-data-with-biztalk-2013/, to create an XML document with few minor enhancements, if a root node is specified, the new xml will be added as a child to it or else a new xml document will be created and the root node will be based on the json message, and as we know BizTalk needs a namespace so we use the ESB toolkit’s add namespace component to add new namespace to the Xml (more than one can be added) created in the previous stage and finally we use the XML disassembler component to inform BizTalk of the new xml document, the following is the code and the pipeline implementation.

Json to xml pipeline component

Json receive pipeline.

IBaseMessage IComponent.Execute(IPipelineContext pContext, IBaseMessage pInMsg)
{
string json;
Trace.WriteLine(“JsonToXmlConverter Pipeline – Entered Execute()”);
Trace.WriteLine(String.Format(“JsonToXmlConverter Pipeline – RootNode: {0}”, Rootnode));
var originalStream = pInMsg.BodyPart.GetOriginalDataStream();

using (TextReader reader = new StreamReader(originalStream))

{

json = reader.ReadToEnd();

}

Trace.WriteLine(String.Format(“JsonToXmlConverter Pipeline – Read JSON Data: {0}”, json));

Trace.WriteLine(String.Format(“JsonToXmlConverter Pipeline – Deserializing JSON to Xml…”));

try

{

// Append deserialized Xml data to master root node.

XmlDocument xmlDoc =!string.IsNullOrWhiteSpace(Rootnode) ? JsonConvert.DeserializeXmlNode(json, Rootnode) : JsonConvert.DeserializeXmlNode(json);

Trace.WriteLine(String.Format(“JsonToXmlConverter Pipeline – Xml: {0}”, xmlDoc.InnerXml));

var output = Encoding.ASCII.GetBytes(xmlDoc.InnerXml);

var memoryStream = new MemoryStream();

memoryStream.Write(output, 0, output.Length);

memoryStream.Position = 0;

pInMsg.BodyPart.Data = memoryStream;

}

catch (Exception ex)

{

Trace.WriteLine(String.Format(“JsonToXmlConverter Pipeline – Exception: {0}”, ex.Message));

}

pInMsg.BodyPart.Data.Position = 0;

return pInMsg;

}

The following video demo’s the end to end working solution: