Talk, talk and more talk about BizTalk

Changing / Removing document namespaces

I recently ran into a requirement to both transmit and receive documents using “Plain Old Xml”. The system we were integrating was not able to understand the concept of namespaces in an Xml document, but BizTalk requires them, as messages are determined by the combination of a document’s Namespace and Root Node.

The solution was two-fold. For incoming messages, we “inject” a pre-determined namespace into the document as soon as it hits BizTalk. For outbound messages, we strip out all namespaces and alias’ just as we are sending it. The best was to do this is using a Pipeline Component.

There are a number of components and methods out there for adding a namespace to an inbound messages, see here and here.  I ended up re-using a sample I found on CodePlex.

To remove namespaces from the outbound messages, I massaged the content of the message using a Regular Expression, and some simple text replacement:

private static string RemoveNamespace(XmlDocument xdoc)
  // Regex to search for either xmlns:nsN="..." or xmlns="..."
  const string pattern = @"xmlns:?(\w+)?=""[\w:/.]*""";
  string xml = xdoc.OuterXml;

  Regex replace = new Regex(pattern);
  // Replace all occurances of the namespace declaration
  string temp = replace.Replace(xml, String.Empty);
  foreach (Match match in replace.Matches(xml))
    // Loop through each Match in the Regex, this gives us the namespace aliases found
    if (match.Success && match.Groups.Count > 1)
      if (!String.IsNullOrEmpty( match.Groups[1].Value))
        Regex alias = new Regex(@"\b" + match.Groups[1].Value + ":");
        // Replace all occurances of the
        temp = alias.Replace(temp, String.Empty);
  return temp;

The regular expression identifies namespace declarations, whether they declare an alias or not.  We then iterate all of the matched aliases, removing them from the target xml document.

Edit: I have added a link to cut-down sample project, detailing exactly how the pipeline component should be implemented.  Click here to download.

Edit2: Modified the regex pattern slightly so it also accounts for elements declared in the “empty” namespace.


June 26, 2012 Posted by | BizTalk, Pipeline | , , | 3 Comments

Received a “System.NotImplementedException” in custom pipeline component

While developing a custom pipeline component I began receiving a System.NotImplementedException when testing the pipeline from an Isolated Host.

After a bit of research, we found the following:

Turns out the problem originates from the Http Adapter, which implements the Setter on the MessagePart.BodyPart.Data property, but not the Getter.

The solution was to change the code that retries the message stream from using MessagePart.BodyPart.Data to using MessagePart.GetOriginalDataStream().

April 28, 2009 Posted by | BizTalk | , , , | Leave a comment

Problems with PropertyBag in custom pipelines

Some advice written by one of my colleagues, Zeb, who spent some time wrestling with a custom pipeline

I was recently tasked with building a custom pipeline component. I hit the net to look for some samples on doing this, and the first thing that I noticed was that there appeared to be a million blogs on how to do this, and they were all using the exact same code – right down to even using the same GUID for their class!

There are plenty of things I could write (and maybe I will), but the biggest issue I had was that none of them were really elaborating on the saving and extraction of custom properties. The basics were simple (implement IPersistPropertyBag), but as is so often the case what can seem simple, often turns out to be far from it! (Although it does tend to become simple and obvious in hindsight)

It was a long journey, and hard to debug, as the symptoms weren’t immediately pointing to the cause. So, below are the two biggest issues I had with the PropertyBag, and how to work around them:

Issue 1: Properties are visible in BizTalk, but not in Visual Studio

Now, this one really didn’t make sense at first, and honestly, it still doesn’t! I know the “how”, but not the “why”. Basically, Visual Studio uses reflection on the class to look for public properties and assumes that they are the properties that can be modified from within Visual Studio. BizTalk on the other hand looks at the actual serialized [sic] properties saved into the pipeline (i.e. if you look in the .btp file “Properties” node inside the component).

So, if you do what I did and move your properties into a seperate class (which I did because I wanted to make two versions of the component – one inheriting from FFDasmComp and one from XMLDasmComp), you need to be aware that you also need to expose them in the calling class as seperate public properties or they will not be visible in Visual Studio.

Issue 2: PropertyBag.Read method returning NULL

This was a strange one, as I was getting inconsistent behaviour. Sometimes my component would work, other times it wouldn’t, and my code changes did not appear to be impacting on the success rate.

The lucky break came when I noticed that the Load method was being called twice, and each instance was returning different values. It appears that BizTalk was calling Load once with the information that was saved when the pipeline was created in Visual Studio, and then a second time to get the customized [sic] values that were modified in the BizTalk Administration Console. The problem here is that if you don’t modify a value in BizTalk, it doesn’t get saved to that property bag, so the read will return NULL.

The way around this is to do the first read and use it to load default values for your properties, and then on the second read only overwrite those values if the Read returns a non-NULL value. I did this by creating a “GetProperty” function that accepted the PropertyBag, the key to read and a default value (which was loaded with the previously read value if available). If Read returned NULL (or error), I loaded the default value.

Thanks for the good work, Zebba.

September 30, 2008 Posted by | BizTalk | , , | 1 Comment