Posts Tagged ‘Functoids’

Exciting news… Version 1.9.1.0 of BizTalk Mapper Extensions UtilityPack for BizTalk Server 2013 R2 and 2013 is now available!

Here’s the change-log for this release:

  • Updated Logical Functoids:
    • The project has sign strong name key solving an issue regarding to “Unable to add BizTalk.Logical.Functoids.dll to the GAC (version 1.9.0.0)” – However, this is a false problem or a BizTalk Deployment Framework that always put functoid assemblies in the GAC, because these functoids are doesn’t need to be place inside the GAC.
  • Updated CRM Functoids:
    • CRM Lookup Functoid: This functoid was updated. This functoid allows you to retrieve a value from CRM lookup field. But now this functoid is also able to performs lookup operation using two different approach: Accessing the CRM database (read-only), for local CRM integration or through the CRM web services if you want avoid giving access to the database or if you have to integrate CRM online.
The new CRM Lookup Functoid

One of the biggest changes in this new version was made by Salvatore Pellitteri that decided to change the previous CRM Lookup Functoid (also created by him) by adding additional features.

This functoid, has the previous one, allows you to retrieve a value from CRM lookup field. However, this new version of the functoid is able to performs lookup operation using two different approach:

  • Accessing the CRM database (read-only), for local CRM integration
  • Through the CRM web services if you want avoid giving access to the database or if you have to integrate CRM online.
Parameters

The functoid takes five mandatory input parameters:

  1. SSO Application Name: the connection parameters are stored inside SSO. Here you have to specify the application name where you decide to store the settings. This allow you to have multiple CRM environments that you can integrate;
  2. CRM Guid Field Name: key field name of which you want to get the value;
  3. CRM Entity Name: CRM entity name on which the resolution will be performed
  4. CRM Input Field Name: imagining having a “code” as input and you want to know the CRM physical key, in this attribute should specify the name of the “code” field.
  5. CRM Input Value: value from source system to resolve

The output of the functoid is a string, Example: 6erg5r-sdrf56-4dfgt5-6ty5r4-456trt 24

new-CRM-Lookup-Functoid-1910

Installation

Create a SSO application.

SQL Server Lookup

Create the following SSO configuration parameters:

  • CrmConnectionType: “sql”
  • CrmDatabaseConnectionString: specify the CRM database connection string

Open SQL Server management console, connect to CRM database and execute the script under CRMLookup.sql file in project folder.

Local CRM web services lookup

Create the following SSO configuration parameters:

CRM Online web services lookup

Create the following SSO configuration parameters:

You can found and download Source Code, Application Binaries and Documentation in CodePlex BizTalk Mapper Extensions UtilityPack home page:

BizTalk Mapper Extensions UtilityPack
CodePlex

 

or from MSDN Code Gallery:

BizTalk Mapper Extensions UtilityPack for BizTalk Server 2013 R2 (685.6 KB)
Microsoft | MSDN Code Gallery

Exciting news… Version 1.9.0.0 of BizTalk Mapper Extensions UtilityPack for BizTalk Server 2013 R2 and 2013 is now available!

Here’s the change-log for this release:

  • Ten new functoids:
    • Advance Logical AND Functoid
    • Advance Equal Functoid
    • Advance Greater Than Functoid
    • Advance Greater Than or Equal To Functoid
    • Advance Less Than Functoid
    • Advance Less Than or Equal To Functoid
    • Advance Not Equal Functoid
    • Advance Logical NOT Functoid
    • Advance Logical OR Functoid
    • If-Then-Else Functoid
  • Updates on the deployment scripts
What’s new in this version?

Although BizTalk Server provides many functoids to support a range of diverse operations when working with conditional mapping, we are limited to the number of existing operations or otherwise have to use custom XSLT.

This new library – Logical Functoids – includes a suit of functoids to perform a variety of logical operations, often controlling whether a particular element or attribute is created in an output instance message. Most of the Logical Functoids are a replica of the existent Logical Functoids that came out-of-the-box with BizTalk Server with the advantage that these will allow you to connect with others Custom String Functoids. They are fully compatible with existing functoids and don’t produce any more additional code.

biztalk-mapper-extensions-utilitypack-2013-r2-v1-9

See also the reason I decide to create this library here: Why is so hard to make a simple If-Then-Else Functoid? … well, not anymore!

Advance Logical AND Functoid

Use the Advance Logical AND functoid to return the logical AND of input parameters. It determines whether all of the specified input parameters are true.

Parameters

This functoid requires a minimum of two input parameters and a maximum of one hundred:

  • Parameter 1: A value that can be evaluated as either True or False.
  • Parameters 2 – 100: Values that can be evaluated as either True or False.

Returns the logical AND of parameters. True if all of the specified input parameters evaluate to True; False otherwise.

01-Advance-Logical-AND-Functoid

Advance Equal Functoid

Use the Advance Equal functoid to return the value “true” if the first input parameter is equal to the second input parameter. It tests whether the two input parameters are equal.

Parameters

This functoid requires two input parameters:

  • Parameter 1: A value to be tested for equality with the parameter 2.
  • Parameter 2: A value to be tested for equality with the parameter 1.

Returns “True” if the values of the two input parameters are equal; “False” otherwise.

02-Advance-Equal-Functoid

Advance Greater Than Functoid

Use the Advance Greater Than functoid to return the value “true” if the first input parameter is greater than the second input parameter. It tests whether the first input parameter is greater than the second input parameter.

Parameters

This functoid requires two input parameters:

  • Parameter 1: A value to be tested to determine whether it is greater than parameter 2.
  • Parameter 2: A value to be tested to determine whether it is greater than parameter 1.

Returns “True” if the value of the first input parameter is greater than the value of the second input parameter; “False” otherwise.

03-Advance-Greater-Than-Functoid

Advance Greater Than or Equal To Functoid

Use the Advance Greater Than or Equal To functoid to return the value “true” if the first input parameter is greater than or equal to the second input parameter. It tests whether the first input parameter is greater than or equal to the second input parameter.

Parameters

This functoid requires two input parameters:

  • Parameter 1: A value to be tested to determine whether it is greater than or equal to parameter 2.
  • Parameter 2: A value to be tested to determine whether it is greater than or equal to parameter 1.

Returns “True” if the value of the first input parameter is greater than or equal to the value of the second input parameter; “False” otherwise.

04-Advance-Greater-Than-or-Equal-To-Functoid

Advance Less Than Functoid

Use the Advance Less Than functoid to return the value “true” if the first input parameter is less than the second input parameter. It tests whether the first input parameter is less than the second input parameter.

Parameters

This functoid requires two input parameters:

  • Parameter 1: A value to be tested to determine whether it is less than parameter 2.
  • Parameter 2: A value to be tested to determine whether it is less than parameter 1.

Returns “True” if the value of the first input parameter is less than the value of the second input parameter; “False” otherwise.

05-Advance-Less-Than-Functoid

Advance Less Than or Equal To Functoid

Use the Advance Less Than or Equal To functoid to return the value “true” if the first input parameter is less than or equal to the second input parameter. It tests whether the first input parameter is less than or equal to the second input parameter.

Parameters

This functoid requires two input parameters:

  • Parameter 1: A value to be tested to determine whether it is less than or equal to parameter 2.
  • Parameter 2: A value to be tested to determine whether it is less than or equal to parameter 1.

Returns “True” if the value of the first input parameter is less than or equal to the value of the second input parameter; “False” otherwise.

06-Advance-Less-Than-or-Equal-To-Functoid

Advance Not Equal Functoid

Use the Advance Not Equal functoid to return the value “true” if the first input parameter is not equal to the second input parameter. It tests whether the two input parameters are not equal.

Parameters

This functoid requires two input parameters:

  • Parameter 1: A value to be tested for inequality with parameter 2.
  • Parameter 2: A value to be tested for inequality with parameter 1.

Returns “True” if the values of the two input parameters are not equal; “False” otherwise.

07-Advance-Not-Equal-Functoid

Advance Logical NOT Functoid

Use the Advance Logical NOT functoid to return the logical inversion of the input parameter. Use to logically negate the value of the Boolean input parameter.

Parameters

This functoid requires one input parameter only:

  • Parameter 1: A value that can be evaluated as either True or False.

Returns “True” if the specified input parameter evaluates to False; “False” otherwise.

08-Advance-Logical-NOT-Functoid

Advance Logical OR Functoid

Use the Advance Logical OR functoid to return the logical OR of input parameters. The input parameters have to be Boolean or numeric. It determines whether any of the specified input parameters are true.

Parameters

This functoid requires a minimum of two input parameters and a maximum of one hundred:

  • Parameter 1: A value that can be evaluated as either True or False.
  • Parameters 2 – 100: Values that can be evaluated as either True or False.

Returns “True” if any of the specified input parameters evaluate to True; “False” otherwise.

09-Advance-Logical-OR-Functoid

If-Then-Else Functoid

Use the If-Then-Else Functoid to return a value from one of two input parameters based on a condition. If the condition (first input) is True, then the value of the second input parameter is returned, otherwise the Third input is returned.

Parameters

This functoid requires three input parameters:

  • Boolean representing the result of a previous condition
  • The value to be returned if the condition is True.
  • The value to be returned if the condition is False.

If the condition is True, then the value of the second input parameter is returned, otherwise the Third input is returned.

10-If-Then-Else-Functoid

You can found and download Source Code, Application Binaries and Documentation in CodePlex BizTalk Mapper Extensions UtilityPack home page:

BizTalk Mapper Extensions UtilityPack
CodePlex

 

or from MSDN Code Gallery:

BizTalk Mapper Extensions UtilityPack for BizTalk Server 2013 R2 (685.6 KB)
Microsoft | MSDN Code Gallery

Sometimes I ask myself: Why is so hard to make a simple If-Then-Else Functoid, or even so painful to do an If-Then-Else operation, using BizTalk mapper?

I don’t mean to say that it is complicated, quite the opposite, is quite easy to make If…Then…Else statements using the Mapper. You can use If…Then…Else statements, to be completely correct, you can use something related to an If…Then…Else statements, to execute blocks of statements depending on the Boolean value of a condition by, normally, using:

  • One Logical Functoid (Logical Existence, Logical String, Logical Numeric, Equal, Greater Than, Less Than and so on) to determine:
    • whether the Record, Field Element, or Field Attribute node that is linked to it exists or have a valid value in a particular input instance message
    • or if a condition match.
  • One Logical NOT Functoid to negate the Logical Functoid
  • And two Value Mapping Functoids to returns the value that we want to linked based on the result of the condition

BizTalk-out-of-the-box-if-then-else-condition

In this sample, if the “Operation” element is equal to “Create”

  • Then: you will map the value of the element “ValueA” from the source schema to the element “Result” in the destination schema
  • Else (otherwise): you will map the value of the element “ValueB” from the source schema to the element “Result” in the destination schema

So, this functoid chain will provide a secondary path of execution when an “if” clause evaluates to false, the Else path. I said earlier: “something related to an If…Then…Else statement” because, programming speaking, If…Then…Else  statements are implemented by:

//C#
if(condition)
{
    //something if true
}
else
{
    //something if false
}

Or

<!-- XSLT -->
<xsl:choose>
  <xsl:when test="expression">
    ... something if true ...
  </xsl:when>
  <xsl:otherwise>
    ... something if false ...
  </xsl:otherwise>
</xsl:choose>

But in fact what this functoid chain does is two If statements

<!-- something if true -->
<xsl:if test="string($var:v1)='true'">
  <xsl:variable name="var:v2" select="ValueA/text()" />
  <Result>
    <xsl:value-of select="$var:v2" />
  </Result>
</xsl:if>
<!-- something if false (var:v3 contains the negation of var:v1) -->
<xsl:if test="string($var:v3)='true'">
  <xsl:variable name="var:v4" select="ValueB/text()" />
  <Result>
    <xsl:value-of select="$var:v4" />
  </Result>
</xsl:if>

This approach is good for small messages, but even with small messages, the Mapper will add many unnecessary code and operations. Because of that I decided to create a If-Then-Else Functoid to use in these situations and improve a little more the performance of the map, of course, undoubtedly, that the best option and with most performance to make conditions is using custom XSLT code (but this is another story).

The annoying things in using this out-of-the-box functois are:

  • We get these  annoying warnings (but they are useful in many scenarios) when we validate the maps:
    • warning btm1004: The destination node “Result” has multiple inputs. For a destination node to have multiple inputs, one of its ancestors should be connected to a looping functoid.
  • And for a simple if-then-else operation we need to use a minimum of 4 functoids. If we have several conditions inside the map, it will be easily filled with functoids and in result, will become a little confused and sometimes difficult to manager.
  • And, obvious, we will have several unnecessary operations.
So, why is so hard to make an If-Then-Else Functoid?

What I want to archive is create a custom functoid that accepts 3 inputs:

  • A Boolean – the result of a previous Logical Functoid (Logical Existence, Logical String, Logical Numeric, Equal, Greater Than, Less Than and so on)
  • And two inputs

Were the custom Functoid will return a value from one of two input parameters based on a condition.

  • If the condition (first input) is True, then the value of the second input parameter is returned;
  • Otherwise the Third input is returned.

Translating to C# code, will be something like this:

public string IfThenElseOperation(string condition, string trueValue, string falseValue)
{
    if (System.Convert.ToBoolean(condition))
        return trueValue;
    return falseValue;
}

Note: I will not address this topic here, this is content deserved a completely different post and dedicated to the topic, but the best option that you have is create a custom functoid belonging to the String functoid category (if you like it, put a comment in the post and I will address this topic in another time/post).

However, if you do that, you will find that, out-of-the-box, it is impossible to create a custom functoid based on a Logical Functoid and the reason why this is true is that, all Logical Functoids available out-of-the-box with BizTalk only accept the following outputs connection types:

  • ConnectionType.Element
  • ConnectionType.FunctoidAssert
  • ConnectionType.FunctoidNilValue
  • ConnectionType.FunctoidKeyMatch
  • ConnectionType.FunctoidTableLooping
  • ConnectionType.FunctoidValueMapping
  • ConnectionType.FunctoidScripter
  • ConnectionType.FunctoidLogical;

ConnectionType Enumeration: Specifies the types of connections that can be used as inputs or outputs for a functoid. This enumeration has a FlagsAttribute attribute that allows a bitwise combination of its member values.

ConnectionType.FunctoidString is not allowed in all the existing Logical Functoids. And that is the reason why you will find impossible to create a custom functoid based on a Logical functoid (don’t know the reason why Microsoft decide to implement this limitation)

How did I solve (or I overcame) this limitation?

To solve (work around) this limitation, so that I could create and use a custom if-then-else functoid, at the same time be fully compatible with existing functoids and don’t produce any more additional code, I was force to create my own personal custom Logical Functoids:

  • Advance Logical AND Functoid
  • Advance Equal Functoid
  • Advance Greater Than Functoid
  • Advance Greater Than or Equal To Functoid
  • Advance Less Than Functoid
  • Advance Less Than or Equal To Functoid
  • Advance Not Equal Functoid
  • Advance Logical NOT Functoid
  • Advance Logical OR Functoid

Toolbox-with-custom-logical-functoids

That have the same behavior as the out-of-the-box Logical Functoids:

  • Logical AND Functoid
  • Equal Functoid
  • Greater Than Functoid
  • Greater Than or Equal To Functoid
  • Less Than Functoid
  • Less Than or Equal To Functoid
  • Not Equal Functoid
  • Logical NOT Functoid
  • Logical OR Functoid

with the advantage that also accept the String output connection type.

base.OutputConnectionType = ConnectionType.FunctoidString | ConnectionType.Element | ConnectionType.FunctoidAssert | ConnectionType.FunctoidNilValue | ConnectionType.FunctoidKeyMatch | ConnectionType.FunctoidTableLooping | ConnectionType.FunctoidValueMapping | ConnectionType.FunctoidScripter | ConnectionType.FunctoidLogical;

By doing that, I can create my if-then-else custom functoid:

namespace BizTalk.CustomAdvanced.Functoids
{
    [Serializable]
    public class IfThenElse : BaseFunctoid
    {
        public IfThenElse()
            : base()
        {
            //ID for this functoid
            this.ID = 10900;

            // resource assembly must be ProjectName.ResourceName if building with VS.Net
            SetupResourceAssembly("BizTalk.Logical.Functoids.LogicalResources", Assembly.GetExecutingAssembly());

            //Setup the Name, ToolTip, Help Description, and the Bitmap for this functoid
            SetName("IDS_IFELSEFUNCTOID_NAME");
            SetTooltip("IDS_IFELSEFUNCTOID_TOOLTIP");
            SetDescription("IDS_IFELSEFUNCTOID_DESCRIPTION");
            SetBitmap("IDS_IFELSEFUNCTOID_BITMAP");

            //category for this functoid. This functoid goes under the String Functoid Tab in the
            this.Category = FunctoidCategory.String;

            // Set the limits for the number of input parameters. This example: 1 parameter
            this.SetMinParams(3);
            this.SetMaxParams(3);

            // Add one line of code as set out below for each input param. For multiple input params, each line would be identical.
            this.AddInputConnectionType(ConnectionType.AllExceptRecord); //first input
            this.AddInputConnectionType(ConnectionType.AllExceptRecord); //Second input
            this.AddInputConnectionType(ConnectionType.AllExceptRecord); //Third input

            // The functoid output can go to any node type.
            this.OutputConnectionType = ConnectionType.AllExceptRecord;

            SetScriptBuffer(ScriptType.CSharp, this.GetCSharpBuffer());
            HasSideEffects = false;
        }

        private string GetCSharpBuffer()
        {
            StringBuilder builder = new StringBuilder();
            builder.Append("public string IfThenElseOperation(string condition, string trueValue, string falseValue)\n");
            builder.Append("{\n");
            builder.Append("\tif (System.Convert.ToBoolean(condition))\n");
            builder.Append("\t\treturn trueValue;\n");
            builder.Append("\treturn falseValue;\n");
            builder.Append("}\n");
            return builder.ToString();
        }
    }
}

And have the ability to connect my logical functoids to a custom String functoid. Of course you need to use it wisely!

BizTalk-custom-if-then-else-condition

The beauty of this approach is that:

  • We reduce the functoids chain. By using less functoids we simplify the map visually, and this is very useful when you have a lot of conditions, even if they are simple conditions.
  • We will improve the map performance a little more, compared to the use of out-of-the-box functoids
    • Using Custom If-Then-Else Functoid:
<xsl:variable name="var:v1" select="userCSharp:LogicalEq(string(Operation/text()) , &quot;Create&quot;)" />
<xsl:variable name="var:v2" select="userCSharp:IfThenElseOperation(string($var:v1) , string(ValueA/text()) , string(ValueB/text()))" />

    <ns0:Output>
      <Result>
        <xsl:value-of select="$var:v2" />
      </Result>
    </ns0:Output>

public bool LogicalEq(string val1, string val2)
{
	bool ret = false;
	double d1 = 0;
	double d2 = 0;
	if (IsNumeric(val1, ref d1) && IsNumeric(val2, ref d2))
	{
		ret = d1 == d2;
	}
	else
	{
		ret = String.Compare(val1, val2, StringComparison.Ordinal) == 0;
	}
	return ret;
}

public string IfThenElseOperation(string condition, string trueValue, string falseValue)
{
	if (System.Convert.ToBoolean(condition))
		return trueValue;
	return falseValue;
}

public bool IsNumeric(string val)
{
	if (val == null)
	{
		return false;
	}
	double d = 0;
	return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d);
}

public bool IsNumeric(string val, ref double d)
{
	if (val == null)
	{
		return false;
	}
	return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d);
}
    • Using Out-of-the-box Functoids:
<xsl:variable name="var:v1" select="userCSharp:LogicalEq(string(Operation/text()) , &quot;Create&quot;)" />
<xsl:variable name="var:v3" select="userCSharp:LogicalNot(string($var:v1))" />

    <ns0:Output>
      <xsl:if test="string($var:v1)='true'">
        <xsl:variable name="var:v2" select="ValueA/text()" />
        <Result>
          <xsl:value-of select="$var:v2" />
        </Result>
      </xsl:if>
      <xsl:if test="string($var:v3)='true'">
        <xsl:variable name="var:v4" select="ValueB/text()" />
        <Result>
          <xsl:value-of select="$var:v4" />
        </Result>
      </xsl:if>
    </ns0:Output>
  
public bool LogicalEq(string val1, string val2)
{
	bool ret = false;
	double d1 = 0;
	double d2 = 0;
	if (IsNumeric(val1, ref d1) && IsNumeric(val2, ref d2))
	{
		ret = d1 == d2;
	}
	else
	{
		ret = String.Compare(val1, val2, StringComparison.Ordinal) == 0;
	}
	return ret;
}

public bool LogicalNot(string val)
{
	return !ValToBool(val);
}

public bool IsNumeric(string val)
{
	if (val == null)
	{
		return false;
	}
	double d = 0;
	return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d);
}

public bool IsNumeric(string val, ref double d)
{
	if (val == null)
	{
		return false;
	}
	return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d);
}

public bool ValToBool(string val)
{
	if (val != null)
	{
		if (string.Compare(val, bool.TrueString, StringComparison.OrdinalIgnoreCase) == 0)
		{
			return true;
		}
		if (string.Compare(val, bool.FalseString, StringComparison.OrdinalIgnoreCase) == 0)
		{
			return false;
		}
		val = val.Trim();
		if (string.Compare(val, bool.TrueString, StringComparison.OrdinalIgnoreCase) == 0)
		{
			return true;
		}
		if (string.Compare(val, bool.FalseString, StringComparison.OrdinalIgnoreCase) == 0)
		{
			return false;
		}
		double d = 0;
		if (IsNumeric(val, ref d))
		{
			return (d > 0);
		}
	}
	return false;
}
  • You don’t need to deploy any of these custom functoids (advance logical functoids or/and if-the-else functoid) to your production environment, you only need to have then in your development environment to be used inside Visual Studio because all of them are custom inline functoids, i.e., they will add the necessary code inside the XSLT file:
  • And finally, you can use all the custom advance Logical Functoids allow side with the out-of-the-box Logical Functoids without any impact and without producing additional code, because they will produce the exact same code of out-of-the-box Logical Functoids!

BizTalk-custom-and-out-of-the-box-if-then-else-condition-side-by-side

Generated code:

<!-- Custom Functoid -->
<xsl:variable name="var:v1" select="userCSharp:LogicalEq(string(Operation/text()) , &quot;Create&quot;)" />
<xsl:variable name="var:v2" select="userCSharp:IfThenElseOperation(string($var:v1) , string(ValueA/text()) , string(ValueB/text()))" />

<!-- out-of-the-box Functoids -->
<xsl:variable name="var:v3" select="string(Operation/text())" />
<xsl:variable name="var:v4" select="userCSharp:LogicalEq($var:v3 , &quot;Create&quot;)" />
<xsl:variable name="var:v6" select="userCSharp:LogicalNot(string($var:v4))" />

    <ns0:Output>
<!-- Custom Functoid -->
      <Result>
        <xsl:value-of select="$var:v2" />
      </Result>
<!-- out-of-the-box Functoids -->
      <xsl:if test="string($var:v4)='true'">
        <xsl:variable name="var:v5" select="ValueA/text()" />
        <Total>
          <xsl:value-of select="$var:v5" />
        </Total>
      </xsl:if>
      <xsl:if test="string($var:v6)='true'">
        <xsl:variable name="var:v7" select="ValueB/text()" />
        <Total>
          <xsl:value-of select="$var:v7" />
        </Total>
      </xsl:if>
    </ns0:Output>
  </xsl:template>

<!-- Both out-of-the-box Functoids and custom functoids will produce this LogicalEq code! -->
public bool LogicalEq(string val1, string val2)
{
	bool ret = false;
	double d1 = 0;
	double d2 = 0;
	if (IsNumeric(val1, ref d1) && IsNumeric(val2, ref d2))
	{
		ret = d1 == d2;
	}
	else
	{
		ret = String.Compare(val1, val2, StringComparison.Ordinal) == 0;
	}
	return ret;
}

public string IfThenElseOperation(string condition, string trueValue, string falseValue)
{
	if (System.Convert.ToBoolean(condition))
		return trueValue;
	return falseValue;
}

public bool LogicalNot(string val)
{
	return !ValToBool(val);
}

public bool IsNumeric(string val)
{
	if (val == null)
	{
		return false;
	}
	double d = 0;
	return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d);
}

public bool IsNumeric(string val, ref double d)
{
	if (val == null)
	{
		return false;
	}
	return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d);
}

public bool ValToBool(string val)
{
	if (val != null)
	{
		if (string.Compare(val, bool.TrueString, StringComparison.OrdinalIgnoreCase) == 0)
		{
			return true;
		}
		if (string.Compare(val, bool.FalseString, StringComparison.OrdinalIgnoreCase) == 0)
		{
			return false;
		}
		val = val.Trim();
		if (string.Compare(val, bool.TrueString, StringComparison.OrdinalIgnoreCase) == 0)
		{
			return true;
		}
		if (string.Compare(val, bool.FalseString, StringComparison.OrdinalIgnoreCase) == 0)
		{
			return false;
		}
		double d = 0;
		if (IsNumeric(val, ref d))
		{
			return (d > 0);
		}
	}
	return false;
}

May not be the perfect solution, I agree on that but I found a very interesting and useful approach for many scenarios. I hope you enjoy it, because I have been used it a lot lately 🙂

BizTalk-custom-and-out-of-the-box-if-then-else-condition-side-by-side-2

The functoids will be available in the next version of BizTalk Mapper Extensions UtilityPack, until then you have all the source code and samples here:

BizTalk Mapper: How to create a custom If-Then-Else Functoid (18,6 KB)
Microsoft | Code Gallery

It’s always good to analyze code performed by others, please do not consider this a criticism, it is not my intention. Doing that you will, compare technics, learn new things, noted and we become aware of how some transformation rules are made inside the maps… and sometimes, most often when things are done in the wrong way, or not quite correct, we gain inspiration or idea to talk about it. And this is one of them, that in fact, I have seen often happening: Applying conditions (if-then-else) using sometimes complex Functoid chain.

So far nothing new, this is a trivial operation that we normally, or often, do. The thing is that often we do it wrong or not quite well.

I have already addressed the processing model of BizTalk maps on my BizTalk Mapping Patterns and Best Practices book but it is always useful to refer again. BizTalk maps follows the model below:

  • The BizTalk mapping engine traverses the destination schema from beginning to end;
  • The mapping rules are constructed and executed as links are encountered in the destination schema;
  • The information is extracted from the source when a link is encountered in the destination schema.

But you need to be extremely aware, and this is important, that when BizTalk mapper engine reach to a condition rules to construct, all the operation that are present downstream of the condition needs to be translated (executed) before the condition rule itself.

Let’s look to the following example:

Complex-Functoid-Chain-Condition-wrong

Where the basic rule that we want to implement is:

  • If the operation is equal to “insert”
    • Then we need to set, in the Cross Referencing tables, and return an identifier (Set Common ID Functoid), based on some content from the source schema and in some values present or not in the Cross Referencing tables (Get Common ID Functoid), and mapped to the “CommonId” element in the destination schema
  • If the operation is different of “insert”
    • Then we need to retrieve an identifier from the Cross Referencing tables (Get Common ID Functoid), again based on some content from the source schema, and mapped the result to the “CommonId” element in the destination schema

So, to be simple and clear, what the BizTalk mapper engine is doing in the picture above is:

  • It found 2 rules to translate, because we have two links connected with the “CommonId” element
  • In the first rule it will: If the operation is equal to “insert”
    • Get one element from the “keys” record in the source schema and put it into a variable
    • Try’s to retrieve two identifiers’, based on some content from the source schema or static data.
    • From the identifiers’ retrieve earlier, it applies some transformation rule (not important for this demo)
    • Set and return an identifier, based on the content of:
      • one element from the “keys”
      • and the transformation rule, associated to the identifiers’ retrieve earlier
    • And finally, will check if the operation is equal to “insert”
      • Then map the value of the identifier created in the previous step to the element “CommonId”
  • In the second rule it will: If the operation is different of “insert”
    • Try’s to retrieve two identifiers’, based on some content from the source schema or static data.
    • From the identifiers’ retrieve earlier, it applies some transformation rule (not important for this demo)
    • And finally, will check if the operation is different to “insert”
      • Then map the value of the identifier created in the previous step to the element “CommonId”

Are you already seeing the problem with this sample?

Let’s analyze the generated XSLT code and try to see if it makes more sense and detect the problem in a clear way:

<xsl:variable name="var:v14" select="userCSharp:LogicalNe(&quot;insert&quot; , string(@operation))" />
<xsl:variable name="var:v23" select="userCSharp:LogicalEq(&quot;insert&quot; , $var:v22)" />
<xsl:variable name="var:v18" select="ScriptNS1:GetCommonID(&quot;INPUT1&quot; , &quot;INPUT2&quot; , string($var:v17))" />
<xsl:variable name="var:v19" select="ScriptNS1:GetCommonID(&quot;INPUT1&quot; , &quot;INPUT3&quot; , string(keys/myelement/text()))" />
<xsl:variable name="var:v15" select="ScriptNS0:GetValue()" />
<xsl:variable name="var:v20" select="ScriptNS2:GetValue(string($var:v15) , string($var:v18) , string($var:v19))" />

<xsl:if test="string($var:v14)='true'">
     <xsl:variable name="var:v21" select="string($var:v20)" />
     <btsCommonId>
            <xsl:value-of select="$var:v21" />
     </btsCommonId>
</xsl:if>

<xsl:variable name="var:v25" select="ScriptNS1:SetCommonID(&quot;FamilyMemberVehicle&quot; , &quot;CRM&quot; , $var:v24 , string($var:v20))" />

<xsl:if test="string($var:v23)='true'">
     <xsl:variable name="var:v26" select="string($var:v25)" />
     <btsCommonId>
            <xsl:value-of select="$var:v26" />
     </btsCommonId>
</xsl:if>

And now, do you see the problem with this sample?

The problem is that independent of the type of operation, if is an insert or other operation, it will always set an identifier in the Cross Referencing tables! (which by the way in my scenario, will induce problems – violate key). And this happens because the condition was defined at the end of the rule (in the right corner)

Complex-Functoid-Chain-Condition-problem

How you should read the rules

Important Note: basically, there are some exceptions, you always need to read the rules:

  • from top to bottom in the order that they happier in the destination schema
  • and from the left to the right (from the source schema to the destination schema) for a specific link connected to an element, field or record in the destination schema;

So, in this case the solution here is very simple, we need to move the condition to a position further downstream, which will allow to be executed sooner, especially the condition is equal to “insert”, because the second part (get two identifiers’ from the Cross Referencing tables) is common for both rules (then and else).

In this case we need to place the condition before we execute the set and return an identifier from the Cross Referencing tables operation, as the picture bellow shows:

Complex-Functoid-Chain-Condition-right

If we check the XSLT code once again, now we will notice that:

  • We are doing all the common operations before the condition rule to e executed
  • And for each particular scenario we will map the result (not equal to “insert”) or apply more operations and map the result (equal to “insert”)
<xsl:variable name="var:v14" select="userCSharp:LogicalNe(&quot;insert&quot; , string(@operation))" />
<xsl:variable name="var:v18" select="ScriptNS1:GetCommonID(&quot;INPUT1&quot; , &quot;INPUT2&quot; , string($var:v17))" />
<xsl:variable name="var:v19" select="ScriptNS1:GetCommonID(&quot;INPUT1&quot; , &quot;INPUT3&quot; , string(keys/myelement/text()))" />
<xsl:variable name="var:v15" select="ScriptNS0:GetValue()" />
<xsl:variable name="var:v20" select="ScriptNS2:GetValue(string($var:v15) , string($var:v18) , string($var:v19))" />
<xsl:variable name="var:v23" select="userCSharp:LogicalEq(&quot;insert&quot; , $var:v22)" />

<xsl:if test="string($var:v14)='true'">
     <xsl:variable name="var:v21" select="string($var:v20)" />
     <btsCommonId>
            <xsl:value-of select="$var:v21" />
     </btsCommonId>
</xsl:if>

<xsl:if test="string($var:v23)='true'">
     <xsl:variable name="var:v24" select="string($var:v20)" />
     <xsl:variable name="var:v25" select="string(keys/siva_viaturaagregadoid/text())" />
     <xsl:variable name="var:v26" select="ScriptNS1:SetCommonID(&quot;FamilyMemberVehicle&quot; , &quot;CRM&quot; , $var:v25 , string($var:v24))" />
     <btsCommonId>
            <xsl:value-of select="$var:v26" />
     </btsCommonId>
</xsl:if>

Like this scenario there are several, more or less complex, more or less critical. Some of them we don’t “even notice” because everything works well but if we check careful, sometimes will make several unnecessary operations that can induce, or may induce, performance problems in our transformations.

Good practices

As a reference and good practice, when you are implement conditions using Functoids chains, you should make the conditions as early as possible, i.e., put the conditions (if-then-else) as possible as you can in the left side of the Functoid chain.

This will allow you:

  • To group and execute certain task only on the context of the condition (inside the <xsl:if> statement)
  • And better performance because we are reducing the “noise” produced in the XSLT generated code by the compiler.

Easy, isn’t it?
Hope you enjoy it.

In the last days I’ve been migrating old maps from BizTalk Server 2004 to the last 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 other completely crazy.

Today I will address a topic that I, unfortunately, have seen constantly: Reusing Scripting Functoids with Inline C# inside the same map. This is also something that I address in my book: “BizTalk Mapping Patterns & Best Practices

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 among a number of scripts and to use several times inside 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 more easy 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;
}

Different-Scripting-Functoid-With-The-Same-Name-Not-Ok

Because both methods have the name and the same number of parameters, the mapper will interpret has the same, regardless if the code inside the functions are the same of not. 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:

<msxsl:script language="C#" implements-prefix="userCSharp"><![CDATA[ 
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 "";
} 
]]></msxsl:script>

To fixed 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();
}

Different-Scripting-Functoid-With-The-Same-Name-Ok

Once again if you validate the map to see the XSL produced, you can see that in this case both functions are being generated:

 <msxsl:script language="C#" implements-prefix="userCSharp"><![CDATA[ 
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(); 
} 
]]></msxsl:script> 
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 in consideration that BizTalk Mapper engine will save the inline scripts in the Extensible Stylesheet Language Transformations (XSLT) Stylesheet defining the map in the 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> (http://msdn.microsoft.com/en-us/library/533texsx%28v=vs.110%29.aspx)

Reusability

Now let 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 "";
}

Reuse-Scripting-Functoid-Bad-Way

This is a very simple case, now imagine a map with several grid pages and several functoids. The problem is this approach, as we explained earlier, is that if we for some reason change the code of one 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 have:
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 call FormatDate and the second FormatDate2. I’m not joking, I saw this approach being used nearly 8 times (Func1, Func2, Func3, Func4, … Func8) in a map! Of course this solve the problem of the first approach but now you have another! The artifact size deployed will be larger, not critical, but if you can avoid is better. This will happen because in this case all method will be embed in the XSL file that will be deployed to your environment.

  <msxsl:script language="C#" implements-prefix="userCSharp"><![CDATA[ 
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 ""; 
} 
]]></msxsl:script>

Another problem, even worse, of this approach is that, if you need to make some changes in the method… you need to do 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 compile will only take in consideration the first one linked in the map, even if the others have a different code inside they are ignored by the compiler.

Reuse-Scripting-Functoid-Good-Way

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 in 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 only the following declaration:

public string FormatDate(string inputDate, string inputFormat, string outputFormat)

Easy, isn’t it?
Hope you enjoy it.

You can download this tool here:

BizTalk Mapper Tips and Tricks: How To Reuse Scripting Functoids with Inline C# (18,6 KB)
Microsoft | Code Gallery

Exciting news… Version 1.8.0.0 of BizTalk Mapper Extensions UtilityPack for BizTalk Server 2013 is now available!

But before talking about the change-log of this version there is another subject that I want to talk first… This project as two new members that was responsible for all the new functionalities available in this version:

  • Martijn Schiedon, Integration architect at ValueBlue (http://www.valueblue.nl) and a Dutch BizTalk community member.
  • And Salvatore Pellitteri. He is Developer Team Manager in Microsys Srl. He works on integration application projects using BizTalk Server and on business intelligence projects using SQL Server platform. He works with BizTalk Server since the first version and has worked in many big integration project with several Italian enterprise organizations using many technologies like SAP, Oracle, SQL Server, AS400, J.D. Edwards and HL7. Salvatore has his own blog https://pellitterisbiztalkblog.wordpress.com/ on which he shares his experiences.

Here’s the change-log for this release:

  • Seven new functoids:
    • MSCRM Map Helper Base Types Functoid
    • MSCRM Map Helper Guid Functoid
    • MSCRM Map Helper Money Functoid
    • MSCRM Map Helper Option Value Functoid
    • MSCRM Map Helper References Functoid
    • XPath Functoid
    • Add SharePoint 2013 Document Set Functoid

What’s new in this version?

Although BizTalk Server provides many functoids to support a range of diverse operations when working with conditional mapping, we are limited to the number of existing operations or otherwise have to use custom XSLT.

MSCRM Map Helper Base Types Functoid

Use this functoid when you want map CRM base data types such as “xs:string”, “xs:int” and so on.

Parameters

The functoid takes three mandatory input parameters:

  • Source Field: Link from source schema field value.
  • Target Field Name: CRM target field name.
  • Target Field Type: CRM target field type (Example: “xs:dateTime”).

The output of this functoid should be linked to:

  • “/<Schema>/<CRM_Operation>/entity/Attributes/KeyValuePairOfstringanyType/key”.
MSCRM Map Helper Guid Functoid

Use this functoid when you want map CRM guid type.

Parameters

The functoid takes two mandatory input parameters:

  • Source Field: Link from source schema field value.
  • Target Field Name: CRM target field name

The output of this functoid should be linked to:

  • “/<Schema>/<CRM_Operation>/entity/Attributes/KeyValuePairOfstringanyType/key”.

You may use this functoid in combination with CRM Lookup functoid, where first find for entity guid and then use the result to map to the destination schema.

MSCRM Map Helper Money Functoid

Use this functoid when you want map CRM money type.

Parameters

The functoid takes two mandatory input parameters:

  • Source Field: Link from source schema field value.
  • Target Field Name: CRM target field name.

The output of this functoid should be linked to:

  • “/<Schema>/<CRM_Operation>/entity/Attributes/KeyValuePairOfstringanyType/key”.
MSCRM Map Helper Option Value Functoid

Use this functoid when you want map CRM option value type.

Parameters

The functoid takes two mandatory input parameters:

  • Source Field: Link from source schema field value.
  • Target Field Name: CRM target field name.

The output of this functoid should be linked to:

  • “/<Schema>/<CRM_Operation>/entity/Attributes/KeyValuePairOfstringanyType/key”.
MSCRM Map Helper References Functoid

Use this functoid when you want map CRM reference type.

Parameters

The functoid takes three mandatory input parameters:

  • Source Field: Link from source schema field value.
  • Target Field Name: CRM target field name.
  • Entity Name: CRM referenced entity.

The output of this functoid should be linked to:

  • “/<Schema>/<CRM_Operation>/entity/Attributes/KeyValuePairOfstringanyType/key”.
MSCRM Map Helper Functoids

These functoids allow you to Integrate Directly with the Dynamics CRM SOAP API, avoiding the use of inline XSLT Call template script functoid.

MSCRM requires that different data types are specified in a different way. For this reason, we provide a set of functoid each for specific data type..

Use this functoids in two steps:

First Step

MSCRM-Map-Helper-Functoids-1

Second Step

MSCRM-Map-Helper-Functoids-2

XPath Functoid

This functoid natively integrates custom XPath queries in the BizTalk mapper. This unique functoid which is a powerful competitor to the ScripterFunctoid or a custom XSLT stylesheet and mixes exceptionally well with other functoids.

Parameters

The functoid takes one mandatory input parameter and one optional parameter:

  • The first parameter specifies an absolute or relative XPath expression, which becomes a native part of the generated XSLT.
  • The (optional) second parameter is a link to the source tree node that becomes the (looping) context for the XPath expression.

This defines the current context node for the XPath expression and allows the use of relative XPath expressions. Additionally, the mapper will generate a looping construct for that linked node where appropriate.

The functoid output can be linked to a destination schema node or serve as input to other functoids.

XPath-Custom-Functoids

See more information at The case of the forgotten Functoid – By Martijn Schiedon

Add SharePoint 2013 Document Set Functoid

Creates a Document Set in an existing SharePoint 2013 List. It is a requirement that the SharePoint list contains a custom content-type of type document set.

Parameters

The following parameters are required:

  • string siteUrl = SharePoint Site Url
  • string listName = SharePoint List Name containing the custom content-type Document Set
  • string docSetContentTypeName = Document Set Content Type name
  • string newDocSetName=Name of the to document set to created

Comment: An custom content-type of type documentset needs to be available in SharePoint.

You can found and download Source Code, Application Binaries and Documentation in CodePlex BizTalk Mapper Extensions UtilityPack home page:

BizTalk Mapper Extensions UtilityPack
CodePlex

 

or from MSDN Code Gallery:

BizTalk Mapper Extensions UtilityPack for BizTalk Server 2013 (628.8 KB)
Microsoft | MSDN Code Gallery

Exciting news… Version 1.7.0.1 of BizTalk Mapper Extensions UtilityPack for BizTalk Server 2013 is now available!

Project Description

BizTalk Mapper Extensions UtilityPack is a set of libraries with several useful Functoids to include and use it in a map, which will provide an extension of BizTalk Mapper capabilities.

Here’s the change-log for this release:

  • Fixes bugs in the String Replace Functoid
What’s new in this minor version?

This is a minor release of this project that is intended to fix some one minor problem reported in the String Replace Functoid.

It was reported that when trying to be replace a Carriage Return\Line Feed (“\r\n”) inside an element the functoid didn’t work and the reason way this happen is that the XSLT code will translate the string “\r\n” to “\\r\\n”. This release will fix that problem. It may not work for every “special characters” however if you find some more problems you can report them that we will address them.

You can found and download Source Code, Application Binaries and Documentation in CodePlex BizTalk Mapper Extensions UtilityPack home page:

BizTalk Mapper Extensions UtilityPack
CodePlex

 

or from MSDN Code Gallery:

BizTalk Mapper Extensions UtilityPack for BizTalk Server 2013 (628.8 KB)
Microsoft | MSDN Code Gallery

After two days ago we released version 1.7.0.0 for BizTalk Server 2013, today is the time of BizTalk Mapper Extensions UtilityPack for BizTalk Server 2010 to be published and available for download!

This release will include all the new functionalities implemented by René Brauwers that were described in my last post: BizTalk Mapper Extensions UtilityPack for BizTalk Server 2013 Updated to v1.7.0.0

This means that we are still maintaining all the features available for BizTalk Server 2013 and 2010.

You can also find a shorter version of this project with less features for BizTalk Server 2009/2006 here: BizTalk Mapper Extensions UtilityPack for BizTalk Server 2006/2009

You can found and download Source Code, Application Binaries and Documentation in CodePlex BizTalk Mapper Extensions UtilityPack home page:

BizTalk Mapper Extensions UtilityPack
CodePlex

 

or from MSDN Code Gallery:

BizTalk Mapper Extensions UtilityPack for BizTalk Server 2010 (905.0 KB)
Microsoft | MSDN Code Gallery

Exciting news… Version 1.7.0.0 of BizTalk Mapper Extensions UtilityPack for BizTalk Server 2013 is now available!

But before talking about the change-log of this version there is another subject that I want to talk first… This project as a new member that was responsible for all the new functionalities available in this version, my friend René Brauwers.

René is a senior Microsoft integration specialist at Motion10 with its head office in the Netherlands (www.motion10.nl). His career started in 2000 as a web developer/designer on the Microsoft platform. At the end of 2002 he got involved in the EAI/BPM world where he started of with WebMethods and did this for the next 3 years. In 2005 he changed his focus back to the Microsoft integration stack and as such got introduced to BizTalk Server 2004. Since 2005 he has been working with almost all versions of BizTalk Server and the last few years he has been specializing in Cloud integration with the Windows Azure platform and hybrid integration scenarios. René has his own blog http://blog.brauwers.nl on which he shares his BizTalk, .NET and Azure experiences.

Here’s the change-log for this release:

  • Two new functoids:
    • String Remove Leading Zeros Functoid
    • Get Windows Azure ACS Wrap Token Functoid
  • New deployment process using PowerShell script
  • New documentation
What’s new in this version?

Although BizTalk Server provides many functoids to support a range of diverse operations when working with strings or working/connecting with Windows Azure, we are limited to the number of existing operations. This new version will provide a new library that enables you to obtain an authentication token from the Windows Azure Access Control Service and new String operations.

This version will also provide a new simplify deployment process using PowerShell script.

Get Windows Azure ACS Wrap Token Functoid

This functoid allows you to obtain an ACS WRAP access token in order to access a Windows Azure BizTalk Services Bridge or Windows Azure Service Bus resources. Note this token needs to be added to the outbound request message Http Header. In order to do so use the Authorization key and assign it’s value as ‘WRAP access_token={RECEIVED TOKEN}’

Parameters:

The functoid takes four mandatory input parameters:

  • A string issuerName – Issuername belonging to the BizTalk Service namespace or Windows Azure Service Bus namespace
  • A string issuerKey – Issuerkey belonging to the BizTalk Service namespace or Windows Azure Service Bus namespace
  • A string endPoint – Full Uri pointing to the BizTalk Service Bridge or Windows Azure Service Bus queue/topic
  • A string windowsAzureACSNamespace – BizTalk Service or Service Bus ACS namespace name

NOTE:

Service Bus ACS namespace should be in format {namespace}-sb.
In case of doubt please log in to the Windows Azure Management Portal. Select Service Bus. Make a note of the name of the namespace to use and append –sb to it. You now have your ACS namespace (i.e. acme-sb)

BizTalk Services ACS namespace should be in format {namespace}{number}-bts
In case of doubt please log in to the Windows Azure Management Portal. Select BizTalk Services. Select the correct BizTalk Service and select Connection Information. A window will pop up containing the namespace (i.e. acme123-bts)

The output of the functoid is a string, Example:  net.windows.servicebus.action=Listen%2cManage%2cSend&http%3a%2f%2fschemas.microsoft.com%2faccesscontrolservice%2f2010%2f07%2fclaims%2fidentityprovider=https%3a%2f%2facsnamespace-bts.accesscontrol.windows.net%2f&Audience=http%3a%2f%2fnamespace.biztalk.windows.net%2fdefault%2f%2fRCVINBOUND&ExpiresOn=1390169379&Issuer=https%3a%2f%2fnamespace2786-bts.accesscontrol.windows.net%2f&HMACSHA256=pHxuXvfPSkvq4TRyB5F%2fj%1fUtC1m3TyQKEJ6%2bkO8mhQg%3

The output should then be added to the Authorization http header of the outbound message. Example: [“Authorization”] = String.Format(“WRAP access_token=\”{0}\””, <YOUR TOKEN>);

Get-Windows-Azure-ACS-Wrap-Token-Functoid

String Remove Leading Zeros Functoid

This functoid allows you to remove any leading zeros from an input string.

Parameters:

The functoid has one mandatory parameter:

  • Input string which contains leading zeros which need to be removed.

The output of the functoid is an integer which is equal to the input instance but than with the leading zeros removed.

String-Remove-Leading-Zeros-Functoid

You can found and download Source Code, Application Binaries and Documentation in CodePlex BizTalk Mapper Extensions UtilityPack home page:

BizTalk Mapper Extensions UtilityPack
CodePlex

 

or from MSDN Code Gallery:

BizTalk Mapper Extensions UtilityPack for BizTalk Server 2013 (628.8 KB)
Microsoft | MSDN Code Gallery

I finally fulfill the promise to upgrade BizTalk Mapper Extensions UtilityPack for BizTalk Server 2006/2009 with all FunctoIds that are currently available for the 2010 and 2013 versions of this project… and if memory serves me correctly, the last version was published on Nov 18, 2010 with only 6 FunctoIds!

This means there’s plenty of new features for BizTalk Server 2006/2009 in this project… a total of 17 new FunctoIds.

Project Description

BizTalk Mapper Extensions UtilityPack is a set of libraries with several useful functoids to include and use it in a map, which will provide an extension of BizTalk Mapper capabilities. This is the list of previous functoids available:

What’s new in this version for BizTalk Server 2006/2009?

Conversion Functoids

  • Convert datetime format Functoid: This functoid allows you to convert datetime format.

Dynamic Generators Functoids

  • Tiny Id Generator Functoid: This functoid allows you to generate a new Tiny Id.

Configuration Functoids

  • BTSNTSvc Config Get Functoid: This functoid allows you to get configuration parameters from BTSNTsvc.exe.config. If there is no section specified, the functoid reads from the AppSettings.
  • System Environment Variable Get Functoid: This functoid allows you to get configuration parameters from machine System Environment Variable.
  • Custom Config Get Functoid: This functoid allows you to get configuration parameters from a custom configuration file.
  • Windows Registry Config Get Functoid: This functoid allows you to get configuration parameters from Windows Registry.
  • SSO Config Get Functoid: This functoid allows you to get configuration parameters from SSO Database.
  • Rule Engine Config Get Functoid: This functoid allows you to obtain a definition value from a Vocabulary in the Business Rules Engine.

CRM Functoids

  • CRM Lookup Functoid: This functoid allows you to retreive a value from CRM lookup field.

String Functoids

  • String Constant functoid: This functoid allows you to set constant values (strings) inside de maps.
  • String ToTitleCase functoid: This functoid allows you to Converts the specified string to title case (except for words that are entirely in uppercase, which are considered to be acronyms).
  • String Advance Compare Functoid: This functoid allows you to compare two specified String objects, ignoring or honoring their case, and returns an boolean that indicates if they are equal or not.
  • String Replace Functoid: This functoid returns a new string in which all occurrences of a specified string (second parameter) found in the first string are replaced with another specified string (third parameter).
  • String Normalize Functoid: This functoid allows you to normalize the text. It will remove two or more consecutive spaces and replace them with a single space, remove two or more consecutive newlines and replace them with a single newline and “condense” multiple tabs into one.
  • String PadLeft Functoid: This functoid allows you to set a new string that right-aligns the characters in this instance by padding them on the left with a specified Unicode character, for a specified total length.
  • String PadRight Functoid: This functoid allows you to set a new string that left-aligns the characters in this string by padding them on the right with a specified Unicode character, for a specified total length.

Custom Advanced Functoids

  • Default Value Mapping functoid: The Default Value Mapping have a simillar but different behaviour. You can use the Default Value Mapping functoid to return a value from one of two input parameters. If the value of the first input parameter is Null or Empty, then the value of the second input parameter is returned, otherwise the first input is returned.

Also this means that now all versions of this project are equal!

You can found and download Source Code, Application Binaries and Documentation in CodePlex BizTalk Mapper Extensions UtilityPack home page:

BizTalk Mapper Extensions UtilityPack
CodePlex

 

or from MSDN Code Gallery:

BizTalk Mapper Extensions UtilityPack for BizTalk Server 2006/2009 (601.5 KB)
Microsoft | MSDN Code Gallery