Tuesday, November 19, 2013

Base64 encode/decode part of messages in map

This post is to show how to base64 encode or decode a part of a message (or the entire input message for that matter) and output the resulting string in an element in the output message.

The technique used allows for execution of inline C# (or VB) code from another script functoid using inline XSLT / XSLT Template.

The input and output schemas looks like this:




In the example, our entire input message should be base64 encoded and the resulting string output to the EncodedData element in the output message. This element is of the type xs:string.

First, we create a script functoid to hold our inline C# code for base64 encoding of the input node. When building such a method, one might first try to use string as the datatype for the input which will result in just the inner xml being transferred to the method. This is since the data from our XSLT call will be of the type MS.Internal.Xml.Cache.XPathDocumentNavigator. We therefore declare the input variable as XPathNavigator instead to get access to the full XML node. The base64 encoding is done using the System.Text.Encoding class together with the System.Convert class.

public string Base64EncodeData(XPathNavigator param1)
{
    byte[] bytesToEncode =

        System.Text.Encoding.UTF8.GetBytes(param1.OuterXml);
    string encodedText = Convert.ToBase64String(bytesToEncode);

    return encodedText;
}


This functoid will not be connected to any node, but just left to "hang" in the map since we call it manually from another script functoid. Another solution to have it a bit cleaner would be to place this code in an external assembly and call that, but sometimes it is nice to have everything in the map.

Next we create a script functoid and connect it to the destination element. We set the following Inline XSLT code:

<xsl:variable name="data">
  <xsl:copy-of select="/" />
</xsl:variable>

<xsl:element name="EncodedData">
  <xsl:value-of select="userCSharp:Base64EncodeData($data)" />
</xsl:element>

We first declare a variable that holds a copy of our source node which we simply specify using xpath.
Then we call the previously configured method doing the encoding, and send the resulting data to our created destination element.

The map will now look like this:



The result from sending in a test XML is an XML with the entire original contents base64 encoded in an element.



4 comments:

  1. Hi Marcus,

    Thanks for this article. It was very helpful for me. Do you have an example of decoding also?

    Regards,
    Teemu

    ReplyDelete
  2. Certainly Teemu!
    I'll write a new post about decoding and publish it as soon as possible.

    ReplyDelete
  3. Teemu, please see the post I just published with a part 2 on how to reverse the functionality above. http://thoughtsofmarcus.blogspot.se/2014/06/base64-encodedecode-part-of-messages-in.html

    ReplyDelete
  4. Thanks, very helpful!

    ReplyDelete