I want to give another plug for these functoids. It was first reviewed by Eliasen in 3 posts, here, here and here..
These functoids are quite old and were first written in 2004. There are two functoids, one for use in maps within an orchestration and one for use on in a map on a receive port extract values from the message context within a map.
I found the receive port version very useful in a messaging only solution that I describe below. I had designed a messaging only solution were;
- A DB2 receive port sends to a request response WCF basic HTTP port.
- The SOAP response is then transformed to a DB2 request before sending to another DB2 send port.
- A custom value in the SOAP Header of the response message has to be copied into one of the attributes in the DB2 request that is sent to the DB2 send port. An example of the custom header and a value of NaitTransactionIdentifier is
The third requirement could be easily meet if we used an orchestration because we could access the WCF.InBoundCustomHeader from the context of the message but how do you do access the values in the context if you are only going to use maps, send ports, receive port and receive locations and pipelines?
The solution was to ;
- Add a custom pipeline as the receive pipeline of the request response WCF basic HTTP port that contains the ContextAccessorProvider custom pipeline component. This saves the context to static variable that can be accessed by the ContextAccessor functoid.
- Create a map that uses the Context Accessor functoid to get the value of WCF.InBoundCustomHeader context property and configure it as the inbound map.
- The settings on the ContextAccessor functoid are InboundHeader and http://schemas.microsoft.com/BizTalk/2006/01/Adapters/WCF-properties.
- The output of the Context Accessor functoid is passed to scripting functoid. (“ I had to modify the code for my requirements to allow the output to be directed to the input of another functoid (OutputConnectionType = ConnectionType.All). At the moment, the output can only be directed to a field. (To enable this you need to choose a functoid category that is not "For internal use only." (see: http://msdn.microsoft.com/en-us/library/microsoft.biztalk.basefunctoids.functoidcategory.aspx). I chose FunctoidCategory.String.” – Anonymous comment on the CodePlex ContextAccessor site )
- The settings for the scripting functoid are
- I used the NAITTransactionIdentifier using this C# snippet to get the NAITTransactionIdentifier
/// <summary>Grab content from element in XML String without creating an XMLDocument
/// <para>If the string is not a date it is returned unchanged.</para>
/// <param name="sXMLFragment">A XMLFragment as string. That can be escaped</param>
/// <param name="sTag">The closing tag string i.e </tagString></param>
/// <returns>Content of XML Element as string</returns>
public static string GetContentOfXMLElementFromXMLFragment(string sXMLFragment, string sTag)
string retVal = String.Empty;
var callToken = TraceManager.CustomComponent.TraceIn(@"<" + sTag + ".*>([^<]*)</" + sTag + ">"); ///
Match match = Regex.Match(System.Net.WebUtility.HtmlDecode(sXMLFragment), @"<" + sTag + ".*>([^<]*)</" + sTag + ">");
retVal = match.Groups.Value;
In summary the ContextAccessor functoid can very useful in messaging only solutions.