Dealing with web services returning byte[] in BizTalk

Published on : Nov 5, 2008

Category : BizTalk Server

Saravana

Author

You can download the entire article as a PDF document. Dealing with web services returning byte[] in BizTalk
Recently I saw some postings in the BizTalk newsgroup asking how we can handle web service operation that returns a byte[]. Even though it’s a trivial task, you need to be aware of certain things. Below is my simple web service operation, which returns a byte[]. For simplicity, I just got this one operation which can return either a simple string, or some form of xml or some binary data . web service operation When you invoke your web service from Internet explorer, you’ll get the result something similar to the one shown below (This is the data you’ll get inside your orchestration as well).
<base64Binary xmlns="http://9b957340-adba-3234-91ea-46a5c9bff530/">dGhpcyBpcyBhIHRlc3Q=</base64Binary>
Adding a web reference to the above service inside your orchestration project, will create a schema (Reference.xsd) with a single root element called “base64Binary” of xsd type “base64Binary” as shown below.
<xs:element name="base64Binary" nillable="true" type="xs:base64Binary" />

Orchestration:

The sample orchestration used for this demonstration is shown below: orchestration

Scenario #1: byte[] contains some string data:

There are a couple of ways you can deal with this scenario.

Option 1: Using map:

In this approach, you can use the scripting functoid and write an inline script as shown below. It important you use the correct encoding methods to parse the string. In this case it was encoded using UTF8 on the web service.  
   1: public string GetString(string param1)
   2: {
   3: byte[] b = System.Convert.FromBase64String(param1);
   4: return System.Text.Encoding.UTF8.GetString(b);
   5: }
  encoded using UTF8 on the web service

Option 2: Using xpath function and helper class:

In this approach we use the orchestrations xpath function to get hold of the binary base64 data as shown below and pass it to a helper method to get the corresponding data.
   1: base64Data = xpath(WS_GetBinary_RESP.GetBinaryResult, "string(/*[local-name()='base64Binary' and namespace-uri()='http://9b957340-adba-3234-91ea-46a5c9bff530/'])");
   2: text = Helper.Utility.GetString(base64Data);
base64Data is a variable of type string
You can download the entire article as a PDF document. Dealing with web services returning byte[] in BizTalk

Helper method:

clip_image008[1]

Scenario #2: byte[] contains some xml data:

This scenario is similar to our previous simple text scenario, only difference here is we modified our helper method to parse and load the xml data into XmlDocument object as shown below.

Helper method:

base64Data

Scenario #3: byte[] contains some binary data:

Dealing with binary data is bit interesting. You need to understand some of the basic points here.
  1. The parts in the multi-part orchestration message can hold any data; there is no restriction to put only xml data in the message parts.
  2. If you define a message variable of type System.Xml.XmlDocument, you can assign an XLANGMessage, which in turn can be a multi-part message with or without xml data in any of the parts. As long as you are not trying to validate it or use any xpath syntax on it, there won’t be any errors.
  3. When constructing an XLANGMessage with a stream, the stream type must either implement IStreamFactory or be a MemoryStream (http://msdn.microsoft.com/en-us/library/aa995576.aspx ).
In this approach we are going to make use of all the above mentioned points. First in our helper dll, we’ll create a class called CustomStreamFactory which inherits from IStreamFactory and implement the interface method CreateStream as shown below. CustomStreamFactory As you can see its a very simple implementation, the class constructor take a byte[] and assign it to a member variable. CreateStream interface method creates and returns a new MemoryStream using the data in member variable.

Helper method:

We create a helper method as shown below to populate the content of the first part with our binary data using XLANGPart, LoadFrom method: clip_image014[1] The syntax here is bit strange, we are not passing the XLANGMessage as ref or out parameter. But that’s how its been documented and it works!! Now within the orchestration expression shape you can assign the message as shown below: construct MSG_XMLDOC { MSG_XMLDOC = new System.Xml.XmlDocument(); Helper.Utility.GetBinary(MSG_XMLDOC,base64Data); } If you send the above message(MSG_XMLDOC) to a file drop location with .jpg extension, you will see the image returned from the web service. TIP: The above syntax in an expression shape is equivalent to putting the code inside a message assignment shape within a Construct shape. In fact you could have just used our scenario 3 to handle simple text(scenario 1) and xml data (scenario 2). Nandri! Saravana
You can download the entire article as a PDF document. Dealing with web services returning byte[] in BizTalk