Acknowledging a Subtle Change in BizTalk Server 2013

By Nick Hauenstein

This post is the second in a weekly series that will highlight things that you will need to know about new features in BizTalk Server 2013. This week, we will examine a subtle change that didn’t even make the new features list, but could change the way you configure your X12 integration solutions.

Many of you who had previously downloaded and installed BizTalk Server 2010 CU3 did so to take advantage of a nice new feature in that CU — namely the ability to Generate 999 acknowledgements (in place of the already generated 997’s). The process for generating 999’s with CU3 was not necessarily intuitive, and somewhat limiting. It involved creating a custom pipeline with the EDI disassembler and toggling the Use 999 Acknowledgement instead of 997 property (that only shows up in the pipeline designer) to True.


While this was a huge improvement over some of the quickly hacked together solutions that had sprung up to tackle this challenge in the meantime, it was still lacking.

What if I already had lots of different semi-customized pipelines that needed this change? What if I want to use the same receive location to receive messages from multiple parties that will each have unique requirements for the types of acknowledgements they receive? Then I had some challenges ahead of me that were pretty boring at best, and/or unhappy and non-trivial at worst.

In the end, the setting of using a 999 (as opposed to a 997) wasn’t really tied to a particular agreement or business profile, and it required custom development to implement. Both of which, could have been better.

The New Way to 999

BizTalk Server 2013 introduces a new way to configure this, while allowing us to use out of the box components and update the setting at the agreement level. Just head over to where you would typically opt-in to generating a 997, and you will find this lovely drop-down list:


Another thing that you will notice in the list, is that it lists both the 4010 and 5010 versions of the 997 as well. As one might expect, these same selections are also available to be configured at the Business Profile level as well.

Worth it

This is definitely welcome change, that will hopefully serve to prevent the spread of developer heartburn. Not only does this make an existing feature (since 2010 CU3) more visible, it also makes it more flexible and eliminates the requirement for custom development / deployment. This change alone – which didn’t even make the list of new features – may make it worthwhile to upgrade (depending on the complexity of your existing and upcoming X12 integrations).

Starting the Journey

If you’re just now starting the journey using BizTalk Server to tackle your X12 or EDIFACT integrations, and need a place to start, be sure to check out QuickLearn Training’s BizTalk Expert Series: EDI class. If you’re new to the BizTalk world, you have some time before the next EDI class to get into our BizTalk 2013 Developer Immersion class, which will take you from 0 to creating enterprise-scale integrations in 5 action-packed days.

What the BizTalk Server 2013 Mapper Updates Mean for You

By Nick Hauenstein

This blog post represents the first in a weekly series that will highlight things you need to know about new features in BizTalk Server 2013. This week we will look at the new mapping engine and how the underlying changes in the engine might effect the behavior you see when using the BizTalk Mapper.

If you look at the list linked above, you find this:

The Mapper uses the XSLCompiledTransform class. Previous BizTalk Server versions used the XslTransform class, which is obsolete. The XSLCompiledTransform class provides performance enhancements, including:

  • Once the Load method completes successfully, the Transform method can be called simultaneously from multiple threads.
  • The new XSLT processor compiles the XSLT style sheet to a common intermediate format. Once the style sheet is compiled, it can be cached and reused.

For more information on the XSLCompiledTransform class, go to XslCompiledTransform Class.

The mapper now uses the XslCompiledTransform class, a class which was the result of a redesign of the XSLT architecture in the Visual Studio 2005 release (.NET 2.0 timeframe).  While load time of a transform using this class can be longer (since the transform must be compiled upon load), if cached it can yield a 4-fold performance improvement for transforms. Will we see this same level of improvement when used within the context of a BizTalk map? Not quite, but it will definitely be noticeable.

There is a fairly detailed blog post on the XslCompiledTransform class from the XmlTeam written around that time as well. I’m not going to re-hash all of that content here, though you should definitely take a look at the table under the Discretionary Behaviors heading. That table will unveil some things (read: strange edge cases) that used to “just work”, but will now cause exceptions.

Instead of focusing on performance improvement or weird edge cases, in this post, I wanted to look at something a little more common. It surfaced for our team as we were migrating some custom functoids from BizTalk Server 2010 to BizTalk Server 2013. Essentially what we found was that if you attempted to return a null value from a custom functoid, you would receive this error message:


For the benefit of those using Google-fu to attack the same problem, the exception message reads: “Extension functions cannot return null values.”

Really this exception would occur regardless of using a custom functoid. Indeed, you can re-create the same behavior with a Scripting functoid returning null out of an inline C# method.

How to Return Null

This all begs the question, how am I supposed to return null? Well there are a few different cases to consider.

If you’re returning null because it’s cleaner than an empty string, but empty string is not considered a special value on its own, then it’s fairly simple. Toss a null coalescing operator between whatever value might be null and string.Empty. That was the fix that handled our case nicely:

[sourcecode language=”csharp”] public string GetError(string lookupId)<br>{<br>return CachedDatabaseAccess.GetError(new Guid(lookupId)) ?? string.Empty;<br>} [/sourcecode]

While that will cause the desired result in the destination message in this case, if I wanted to output null to the destination message I have a few choices still. I can still return string.Empty which will create an empty node in the document, use one of the Logical functoids to prevent a node from being created when it does not return true, or use the Nil Value functoid to set set the output as nil (assuming the destination schema allows it).

Passing Null Around

But what if I’m returning that null value so that it can be passed to another functoid? If both are scripting functoids and they’re both using inline script, I can do this quite easily by making use of a global variable within the map (in the screenshots below it is named result1), and then writing my code to access that in order to request the raw result.

NOTE: This is also a pattern we encourage for maintaining the state of .NET objects through chained functoids (since if they are returned directly the ToString method is called)



That’s all fine and good when things are inline C#, but what if I’m wanting to pass an earlier null value as an input to an external assemblies? Well that’s where things get a little bit trickier. Best bet there right now is to establish a special non-null value that can represent null, and pass that to an external method that wraps a call to the method you actually want to call and translates that value. Either that, or write custom functoids that can share a set of ThreadStatic values and have one of them wrap the call to the external method (though that might be a little bit overkill).

Wrapping it Up

Even though I’ve spent my time talking about one small annoying aspect of upgrading, let me tell you it’s a worthwhile price to pay for the massive performance improvements you’re going to see.

If you want to see how that custom functoid turned out, and interact with it yourself, be sure to check out one of our upcoming BizTalk Server 2013 Developer Deep Dive courses!

See also: