BizTalk Custom Functoid: Extension function parameters or return values which have Clr type Char are not supported

  • Sandro Pereira
  • Nov 20, 2018
  • 4 min read

Back to Errors and Warnings, Causes and solutions, this time with a surprising error that I got while I was testing a custom Functoid that I had developed: Extension function parameters or return values which have Clr type ‘Char’ are not supported.

The full error description was:

Invoking component…

C:\Development\BizTalk Server Project1\BizTalk Server Project1\Map1.btm: warning btm1028: The required field “VarValue” has no incoming link, constant value, or default value.

TestMap used the following file: <file:///C:\Development\BizTalk Server Project1\Schema1_output.xml> as input to the map.

C:\Development\BizTalk Server Project1\BizTalk Server Project1\Map1.btm: error btm1050: XSL transform error: Unable to write output instance to the following <file:///C:\Users\Administrator\AppData\Local\Temp\2\_MapData\BizTalkServerProject1\Map1_output.xml>. Extension function parameters or return values which have Clr type ‘Char’ are not supported.

Test Map failure for map file <file:///C:\Development\BizTalk Server Project1\BizTalk Server Project1\Map1.btm>. The output is stored in the following file: <file:///C:\Users\Administrator\AppData\Local\Temp\2\_MapData\BizTalkServerProject1\Map1_output.xml>

Component invocation succeeded.

BizTalk Custom Functoid type Char are not supported

Again, I caught this error while I was trying to test my custom functoid inside Visual Studio.

The Custom Functoid was invoking the following code:

private string GetCSharpBuffer()
{
    StringBuilder builder = new StringBuilder();
    builder.Append("public string SplitText(string element, int pos, char splitter)\n");
    builder.Append("{\n");
    builder.Append("\tstring[] listValues = element.Split(splitter);\n");
    builder.Append("\tif (listValues != null)\n");
    builder.Append("\t\tif (listValues.Length &gt; pos)\n");
    builder.Append("\t\t\treturn listValues[pos];\n");
    builder.Append("\treturn \"\";\n");
    builder.Append("}\n");
    return builder.ToString();
}

Or, to be easier to read in a clean C# code, that would be like this:

public string SplitText(string element, int pos, char splitter)
{
   string[] listValues = element.Split(splitter);

   if (listValues != null)
      if (listValues.Length &gt; pos)
         return listValues[pos];
   return "";
}

📝 One-Minute Brief

Explains why BizTalk custom functoids fail with the “char[] are not supported” error and shows how to properly handle string and character data types when developing custom functoids.

Cause

Unfortunately, this is a limitation of the BizTalk mapper engine. The type Char is not supported at least on built-in code inside the XSLT, in other words, by using the Functoid SetScriptBuffer functionality:

SetScriptBuffer(ScriptType.CSharp, this.GetCSharpBuffer());

I didn’t test, but it may work if you replace this functionality with the SetExternalFunctionName functionality:

SetExternalFunctionName(GetType().Assembly.FullName, GetType().FullName, "SplitText");

Note: This means that the code will not be inside the XSLT but instead you will be calling an external assembly that needs to be on GAC.

Solution

The simple solution, or let’s call it a workaround, is to use strings instead, either on inputs as output parameters of the Functoid. For that, we just need to replace the above code to this:

private string GetCSharpBuffer()
{
    StringBuilder builder = new StringBuilder();
    builder.Append("public string SplitText(string element, int pos, string splitter)\n");
    builder.Append("{\n");
    builder.Append("\tstring[] listValues = element.Split(Convert.ToChar(splitter));\n");
    builder.Append("\tif (listValues != null)\n");
    builder.Append("\t\tif (listValues.Length &gt; pos)\n");
    builder.Append("\t\t\treturn listValues[pos];\n");
    builder.Append("\treturn \"\";\n");
    builder.Append("}\n");
    return builder.ToString();
}

Or again, in a simple C# form:

public string SplitText(string element, int pos, string splitter)
{
    string[] listValues = element.Split(Convert.ToChar(splitter));

    if (listValues != null)
       if (listValues.Length &gt; pos)
          return listValues[pos];
    return "";
}

By doing that, you will be able to successfully test the Functoid.

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. 

Thanks for Buying me a coffe
Author: Sandro Pereira

Sandro Pereira lives in Portugal and works as a consultant at DevScope. In the past years, he has been working on implementing Integration scenarios both on-premises and cloud for various clients, each with different scenarios from a technical point of view, size, and criticality, using Microsoft Azure, Microsoft BizTalk Server and different technologies like AS2, EDI, RosettaNet, SAP, TIBCO etc. He is a regular blogger, international speaker, and technical reviewer of several BizTalk books all focused on Integration. He is also the author of the book “BizTalk Mapping Patterns & Best Practices”. He has been awarded MVP since 2011 for his contributions to the integration community.

Leave a Reply

Your email address will not be published. Required fields are marked *

The Ultimate Cloud
Management Platform for Azure

Supercharge your Azure Cost Saving

Learn More
Turbo360 Widget

Back to Top