Calling .NET Components From Inline XSLT In BizTalk

Here’s one for you. Last week I encountered a particularly tricky multi-part mapping scenario. I had to build a destination message that contained groupings from the two source messages. Each record in the first source message created a destination node, and each record in the second source message created a destination node directly beneath the related first source record. To make matters tougher, every destination record has an attribute containing a sequential number. So out of this …

<source1>
  <Node1><Node1>
  <Node2></Node2>
</source1>
<source2>
  <NodeRelatedToNode1></NodeRelatedToNode1>
  <NodeRelatedToNode1></NodeRelatedToNode1>
  <NodeRelatedToNode2></NodeRelatedToNode2>
</source2>

The destination was supposed to look like this …

<destination>
  <Node1 page=”1″><Node1>
  <NodeRelatedToNode1 page=”2″></NodeRelatedToNode1>
  <NodeRelatedToNode1 page=”3″></NodeRelatedToNode1>
  <Node2 page=”4″></Node2>
  <NodeRelatedToNode2 page=”5″></NodeRelatedToNode2>
</destination>

The grouping part wasn’t too tough, just used a Scripting functoid with the XSLT Call Template and a little hand written XSL. The hard part was creating the sequential “page” numbers. Those familiar with XSLT know that the “variables” in XSLT are basically constants, so you can’t create a variable and increment it. I considered building some sort of recursion to get my incremented number, but in the end, decided to call a custom .NET component from my map’s XSLT. I built a C# component that had a member variable, and a method called “GetNext()” which incremented and then returned the next sequential number. I then set my map’s Custom Extension XML to an XML document referencing my custom component. Now in my XSLT Call Template I could get the next “page” number each time I built a destination node. Neat!
See here for an example of doing this.

Here’s where a “quirk” was introduced. When I deployed this map, and ran multiple documents through it, the first document had it’s paging correct (e.g. pages 1-5), but the next messages had the wrong values (e.g. 6-10, 11-16, etc). What was happening was that somehow this custom C# component was being shared! The “increment” kept counting on each orchestration call! My C# component wasn’t built as a “static” object, and I assumed that the scope of each custom object was the individual map (or orchestration) instance.

I still have no idea why this happened, but to ensure it wouldn’t keep happening, I added a method to the custom component called “Reset()” which set the counter to 0. Then at the top of the map I call out to that method to ensure that each map starts its counter at 0.

Thoughts as to why this happens? Wild stuff.

Technorati Tags:

Comments

7 responses to “Calling .NET Components From Inline XSLT In BizTalk”

  1. Oleg Gershikov Avatar

    Hi Richard,
    This happens because static .NET components “live” in handler’s context: in our case in BizTalk host instance or IIS if the map runs in SOAP receive location. Unfortunately your solution with Reset() function may cause problems if you have several instances of the same orchestration running simultaneously.
    Sorry for bad news :-).

    I’d try to solve this problem with xslt-only approach. Here is one of the options:

    number(substring(local-name(), 5))])”/>
    number(substring(local-name(), 18))])”/>

    Obviously I don’t know your task and this maybe not what you need, but I hope this helps.
    Good luck.
    Oleg.

  2. Oleg Gershikov Avatar

    Well, xslt was “destroyed” in the previos post. Sorry.

  3. Richard Seroter Avatar

    Hey Oleg,

    Thanks for the post. But class/method ISN’T static. That’s why I assumed it would be stateful only to a given map (or calling orchestration).

  4. Mick Avatar

    Richard – alternative -> could you consider a Custom Functoid that internally uses the beloved c# that you need?

    xslt super fast though πŸ™‚

    Nice one.

  5. […] XSLT In BizTalk Published May 24th, 2007 BizTalk , .NET A while back I wrote about calling external assemblies from within a BizTalk map. A problem I mentioned was that the member variable in the class that the map was calling seemed to […]

  6. manjunathp Avatar
    manjunathp

    Hi Richard,

    It is strange to know that this is happening for non static variables. can you please share a snippet so that i can regenerate this shared scenario.

    This arcticle is uprooting my basics πŸ™‚

    1. Richard Seroter Avatar

      Hi there. Unfortunately, this was quite a while ago, and I don’t have the original code sitting around anymore. Hopefully there’s enough of a description here if you’d like to re-create it!

Leave a reply to manjunathp Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.