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:

7 thoughts on “Json, Send and Receive Pipelines for BizTalk Server.”

  1. Hi,

    Good article. Thanks for sharing.

    Question: I don’t see you use “XmlToJsonConverter” in the send pipeline, but you use “DotNetTypesToJsonConverter”. What is the reason behind this?

    Regards,
    Tuan

  2. Hi I am getting the following error in the json to xml conversion pipeline component

    There was a failure executing the receive pipeline: “Test.Json1.Pipeline.recJson, Test.Json1.Pipelines, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6c68eaf68da2c621
    “Source: “JsonToXmlConverter” Receive Port: “testwq” URI: “D:\wqin\*.*” Reason: Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))”

    Any idea whats going wrong with the pipeline component. ?

      1. the actual error is due to array object in the json file . and the exxception statement is “XmlNodeConverter can only convert JSON that begins with an object”. This can be handled by specifying an array name while deserializing to xml node. For example : xmldoc = JsonConvert.DeserializeXmlNode(“{\”array\”:” + JsonText + “}”, “root”)

  3. the typename property always returns value as null even if defined when using the component in BizTalk 2010.Any specific reason

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: