In the last few days, I’ve been migrating old maps from BizTalk Server 2004 to the latest versions of BizTalk Server: 2013 and 2013 R2, and I have seen several “styles/approaches” to address mappings, some of them great, some of them not so much, and others completely crazy.
Today, I will address a topic I, unfortunately, have seen repeatedly: Reusing Scripting Functoids with Inline C# within the same map. This is also something that I address in my book: BizTalk Mapping Patterns & Best Practices.
📝 One-Minute Brief
This post explains common pitfalls and best practices when reusing Scripting Functoids with Inline C# in BizTalk maps. It clarifies why function name collisions occur, how the BizTalk mapper compiles inline scripts, and the correct approach to safely reuse custom logic within the same map.
Inline scripts are convenient for custom code that you are unlikely to use elsewhere in your application or other maps. In addition to being convenient for one-time scripts, inline scripts are also useful for declaring global variables for use across multiple scripts and to using several times within the same map.
In general, some of the main reasons to use Scripting Functoid are:
- Perform functions otherwise not available with built-in Functoids
- It also allows you to perform complex logic transformations that are impossible to make with built-in Functoids.
- To simplify the map, making it sometimes easier to read, instead of using a complex Functoid chain
- Or simply to optimize the transformation rules
However, you need to have some precautions when using or reusing the same Custom Inline C# scripts inside the Scripting Functoid:
- Function Names Limitation
- Compiler limitations
- Reusability
Function Names Limitation
For each function/method inside the Scripting Functoid, you need to give different Method statements (name of the method + method parameters). If you have the same Method statement with different behaviors inside, for example:
- In the first Scripting Functoid:
public string FormatDate(string inputDate, string inputFormat, string outputFormat)
{
System.DateTime date;
if (System.DateTime.TryParseExact(inputDate, inputFormat,
System.Globalization.CultureInfo.InvariantCulture,
System.Globalization.DateTimeStyles.AssumeLocal, out date))
{
return date.ToString(outputFormat);
}
return "";
}
- And in the second Scripting Functoid:
public string FormatDate(string inputDate, string inputFormat, string outputFormat)
{
if (String.IsNullOrEmpty(inputDate))
return System.DateTime.Now.ToString(outputFormat);
return inputDate;
}
Because both methods have the same name and the same number of parameters, the mapper will treat them as the same, regardless of whether the code inside the functions is identical. In this case, the first mapping rules to be reached is the first scripting functoid, which means that the second code inside the second functoid will be ignored and instead will be executed the exact same code that the first one, which is not what intended to do.
You can validate this map behavior if you validate the map and see the XSL produced:
public string FormatDate(string inputDate, string inputFormat, string outputFormat)
{
System.DateTime date;
if (System.DateTime.TryParseExact(inputDate, inputFormat, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AssumeLocal, out date))
{
return date.ToString(outputFormat);
}
return "";
}
To fix this, we need to give a different name to the second method, for example:
public string ValidateAndFormatDate(string inputDate, string inputFormat, string outputFormat)
{
if (String.IsNullOrEmpty(inputDate))
return System.DateTime.Now.ToString(outputFormat);
return inputDate;
}
Nevertheless, you can give the same method name if the method has a different number of inputs. For example, this case is a valid example:
- In the first Scripting Functoid:
public string FormatDate(string inputDate, string inputFormat, string outputFormat)
{
System.DateTime date;
if (System.DateTime.TryParseExact(inputDate, inputFormat,
System.Globalization.CultureInfo.InvariantCulture,
System.Globalization.DateTimeStyles.AssumeLocal, out date))
{
return date.ToString(outputFormat);
}
return "";
}
- And in the second Scripting Functoid:
public string FormatDate()
{
return System.DateTime.Now.ToString();
}

Once again, if you validate the map to see the XSL produced, you can see that in this case, both functions are being generated:
public string FormatDate(string inputDate, string inputFormat, string outputFormat)
{
System.DateTime date;
if (System.DateTime.TryParseExact(inputDate, inputFormat, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AssumeLocal, out date))
{
return date.ToString(outputFormat);
}
return "";
}
public string FormatDate()
{
return System.DateTime.Now.ToString();
}
Compiler limitations
When you create a script, for example, a C# function, remember to give it a correct name because all scripts with the same name are treated as one by the compiler, regardless of whether the code is equal or not.
You also have to take into consideration that the BizTalk Mapper engine will save the inline scripts in the Extensible Stylesheet Language Transformations (XSLT) Stylesheet defining the map within the msxsl:script element. The following namespaces are supported by default: System, System.Collection, System.Text, System.Text.RegularExpressions, System.Xml, System.Xml.Xsl, System.Xml.Xpath, Microsoft.VisualBasic. You can add support for additional namespaces outside the listed using the namespace attribute of the child element, <msxsl:using>, of the <msxsl:script> element, but this will force us to use an External Custom XSLT file to accomplish the transformation. See more here: XSLT Stylesheet Scripting Using <msxsl:script> (https://docs.microsoft.com/en-us/dotnet/standard/data/xml/xslt-stylesheet-scripting-using-msxsl-script)
Reusability
Now let’s go to the main topic of this post: Reusability of Scripting Functoids with Inline C# inside the same map.
What I normally see is people doing two things:
- Copy and paste the entire method to all the Scripting Functoids – I’m calling that: Reusing in a Bad Way
- In this case, both scripting functoids have the exact same code:
public string FormatDate(string inputDate, string inputFormat, string outputFormat)
{
System.DateTime date;
if (System.DateTime.TryParseExact(inputDate, inputFormat,
System.Globalization.CultureInfo.InvariantCulture,
System.Globalization.DateTimeStyles.AssumeLocal, out date))
{
return date.ToString(outputFormat);
}
return "";
}
This is a very simple case. Now, imagine a map with several grid pages and several functoids. The problem is that, as we explained earlier, if we, for some reason, change the code of one of the scripting functoids that is not the first to be translated by the mapper engine, the changes will not take effect!!!
- Copy and paste the entire method to all the Scripting Functoids and give it a different name! – I’m calling that: Reusing in a Crazy Way.
- In this case, the first scripting functoids have:
public string FormatDate(string inputDate, string inputFormat, string outputFormat)
{
System.DateTime date;
if (System.DateTime.TryParseExact(inputDate, inputFormat,
System.Globalization.CultureInfo.InvariantCulture,
System.Globalization.DateTimeStyles.AssumeLocal, out date))
{
return date.ToString(outputFormat);
}
return "";
}
- And the second one has:
public string FormatDate2(string inputDate, string inputFormat, string outputFormat)
{
System.DateTime date;
if (System.DateTime.TryParseExact(inputDate, inputFormat,
System.Globalization.CultureInfo.InvariantCulture,
System.Globalization.DateTimeStyles.AssumeLocal, out date))
{
return date.ToString(outputFormat);
}
return "";
}
The one difference is that the first one is called FormatDate and the second is FormatDate2. I’m not joking, I saw this approach being used nearly 8 times (Func1, Func2, Func3, Func4, … Func8) on a map! Of course, this solves the problem of the first approach, but now you have another! The deployed artifact size will be larger; not critical, but if you can avoid it, better. This will happen because, in this case, all methods will be embedded in the XSL file that will be deployed to your environment.
public string FormatDate(string inputDate, string inputFormat, string outputFormat)
{
System.DateTime date;
if (System.DateTime.TryParseExact(inputDate, inputFormat, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AssumeLocal, out date))
{
return date.ToString(outputFormat);
}
return "";
}
public string FormatDate2(string inputDate, string inputFormat, string outputFormat)
{
System.DateTime date;
if (System.DateTime.TryParseExact(inputDate, inputFormat, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AssumeLocal, out date))
{
return date.ToString(outputFormat);
}
return "";
}
Another, even worse, problem with this approach is that if you need to make changes to the method… You need to make the same changes in every single functoid! If you want them to work in a coherent and transparent way.
So, what is the best way to reuse Scripting Functoids with inline C#?
Easy! You need to remember that when you have two or more Custom Inline C# scripts with the same Method statement (name of the method + method parameters), the compiler will only take into consideration the first one linked in the map; even if the others have different code inside, they are ignored by the compiler.
When we use Custom Inline C# scripts, the best way to implement reusability is to specify the body function in only one Scripting Functoid, and the remaining ones specify only the function declaration. In this sample, the first Scripting Functoid will have the following code:
public string FormatDate(string inputDate, string inputFormat, string outputFormat)
{
System.DateTime date;
if (System.DateTime.TryParseExact(inputDate, inputFormat,
System.Globalization.CultureInfo.InvariantCulture,
System.Globalization.DateTimeStyles.AssumeLocal, out date))
{
return date.ToString(outputFormat);
}
return "";
}
And the second one is only the following declaration:
public string FormatDate(string inputDate, string inputFormat, string outputFormat)
Easy, isn’t it?
Hope you enjoy it.
Download
THIS SAMPLE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND.
You can download BizTalk Mapper Tips and Tricks: How to create a Global Inline C# Function from GitHub here:
For those looking to move beyond the basics of message transformation, I highly recommend checking out my eBook, BizTalk Mapping Patterns & Best Practices, published in partnership with BizTalk360.
This resource is a deep dive into the real-world challenges of data transformation. It covers:
- Mapping Patterns: From simple field-to-field links to complex structural shifts.
- Performance Optimization: How to build maps that don’t slow down your environment.
- XSLT vs. Functoids: Knowing exactly when to use built-in tools and when to write custom code.
Whether you are maintaining a legacy BizTalk 2010 environment or planning a migration, these patterns are the foundation of clean, maintainable integration.
Download the full eBook here: BizTalk Mapping Patterns & Best Practices
Hope you find this helpful! If you liked the content or found it useful and would like to support me in writing more, consider buying (or helping to buy) a Star Wars Lego set for my son.



Good one!!! It’s really tricky…
Let me use it now, I have similar requirement in the current project. Till now I was doing in the crazy way !
:):) it happens more often than you may think :), it time to change 🙂
Once again great tidbit – thx Sandro, hope you are doing well (had to laugh when I saw the subtitle, I was refactoing some old BTS 2004 maps about 3 years back and what a pain at times)
Hi Sandro. I’m trying to implement this, but on the second functoid I am getting an exception “Inline Script Error: ; expected”, as if it doesn’t realize I’m trying to use the same method statement. The statements do match between the two functoids. I can’t see any differences between my map and yours, but I am able to compile and test with yours successfully. Any suggestions?