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.

Well let’s go back to the topic: you are doing crazy things with your maps!

I was thinking that I had already seen it all, I was thinking that I had already seen it all, but the reality is that I continue to be blown away. While testing a project migration I end up catching this error:

Xlang/s engine event log entry: Uncaught exception (see the ‘inner exception’ below) has suspended an instance of service ‘[MY_ORCHESTRATION_NAME] (1582c665-816d-07db-3dee-1c6a750944a0)’.
The service instance will remain suspended until administratively resumed or terminated.
If resumed the instance will continue from its last persisted state and may re-throw the same unexpected exception.
InstanceId: 4e0d3e55-b481-442d-a2a4-9f4ee6e13fb7
Shape name: Create Client Msg
ShapeId: 0e4a8cba-c6a0-4a0f-ad94-574b2e8ab7ad
Exception thrown from: segment 1, progress 54

Inner exception: A failure occurred while evaluating the distinguished field [MY_FIELD_NAME] against the message part data. The message part data does not contain at least one of the nodes specified by the XPath expression (listed below) that corresponds to the distinguished field. The cause for this error may be that the message part data has not been initialized or that the message part data does not conform to the message part schema. Ensure that the message part data is initialized correctly. XPath expression: /*[local-name()=’ROOT_NAME’ and namespace-uri()=’NAMESPACE’]/*[local-name()=’MY_FIELD_NAME’ and namespace-uri()=”]

Exception type: XPathUpdateException
Source: Microsoft.XLANGs.Engine
Target Site: Void SetDistinguishedField(System.String, System.Object)
The following is a stack trace that identifies the location where the exception occurred
at Microsoft.XLANGs.Core.XSDPart.SetDistinguishedField(String dottedPath, Object val)
at Siva.CRM.EAI.SIVOrchestration.Client.SIV_Client_ClientAccountSubscriber_UpdDel.segment1(StopConditions stopOn)
at Microsoft.XLANGs.Core.SegmentScheduler.RunASegment(Segment s, StopConditions stopCond, Exception& exp)

I got curious to see that this problem, as the error specify clearly, was related to a distinguished field element and it was happening inside a Construct Message that was using a map.

CAUSE

The error details points for the cause of the problem and it is for sure something related to the XPath expression: /*[local-name()=’ROOT_NAME’ and namespace-uri()=’NAMESPACE’]/*[local-name()=’MY_FIELD_NAME’ and namespace-uri()=”], however, the cause may not be exactly the same.

In my case when I opened the map, I easily realize that the field that was promoted as distinguished field was being mapped twice, i.e., two source elements where being mapped to the same destination element what was causing this element to appear twice in the final message even though the destination element is defined as Max Occurs 1 and Min Occurs 0.

wrong-transformation-rule-causing-error-evaluating-distinguished-field

Of course you may know that distinguished fields are essentially XPath aliases, which simply point to the appropriate XML data field. They don’t have a size limitation but they only can appear once. You cannot promote a repeating element.

And you also should know that the map doesn’t validate the input or the output messages in runtime!

And the curious thing was that this particular distinguished field it was not being used inside the orchestration!

SOLUTION

The solution it easy for this case.

First:

  • Don’t promote elements that you are not really using or need to do some logic inside your orchestrations… If you don’t need them, don’t promote them. Distinguished fields cost less than Property Fields but they still have a cost for performance!

Second:

  • Fix the ma rule associated with this element. In my case I decide to remove the “nipc” rule and leave only the “accountId” direct link to the “EntityGuid”

Finally, something that many community members have been requesting me to publish is here! I already made this manual several months ago, however, for several reasons (speaking engagements, publishing other content and so on) I have been delaying its publication. But I have offered this same guide to all my customers.

There are many things to consider when planning this type of installation, often the network infrastructure already exists and BizTalk Server must coexist with other network applications.

Installing BizTalk Server 2013 R2 in a Basic Multi-Computer Environment (User Guide) is a 145 pages detailed installation document that explains how to install, configure and optimize Microsoft BizTalk Server 2013 R2 on a basic multi-computer running Windows Server 2012 R2. This information will help you to plan the installation and configuration of BizTalk Server 2013 R2, applications and components on which it depends.

Contents                                      
  1. BizTalk Server Installation scenario.
  2. The need for a Domain Controller – Windows Groups and Service Accounts.
    1. Create Domain Groups and Users.
    2. Planning the use of a new Organizational Unit.
    3. Windows Groups Used In BizTalk Server.
    4. IIS_WPG and IIS_IUSRS Group.
    5. User and Service Accounts Used In BizTalk Server.
    6. Summary of users and Groups Affiliation.
    7. SQL Server Service Accounts.
    8. References.
  3. Preparing Computers for Installation – Important considerations before set up the servers.
    1. Change the Machine name.
    2. Join the Local Administrators Group.
    3. The user running the BizTalk Server configuration must belong…
    4. Install Critical Windows Updates.
    5. Disable IPv6 (optional).
    6. Turn off Internet Explorer Enhanced Security Configuration (optional).
    7. Disable User Account Control (optional).
    8. Turn Windows Firewall off (optional).
    9. Configure Microsoft Distributed Transaction Coordinator (MS DTC).
    10. COM+ Network Access considerations.
  4. Preparing and Install SQL Server 2014 machine.
    1. Important considerations before set up the servers.
    2. Install SQL Server 2014.
    3. Configure SQL Server Database Mail feature.
    4. Install Service Pack 1 for Microsoft SQL Server 2014.
    5. Configure SQL Server for Remote Connections.
    6. Configured SQL Server protocols – Disable the Shared Memory Protocol, Enable TCP/IP and Named Pipes.
    7. Configure SQL Server Database Engine to listen on a specific TCP Port (optional).
    8. Configure SQL Analysis Server to listen on a specific TCP Port (optional).
    9. Configuring Microsoft Distributed Transaction Coordinator (DTC) to work through a firewall or network address translation firewalls (optional).
    10. List of ports between BizTalk Server and SQL Server (optional).
    11. Configure Firewall on SQL Server machine (optional).
      1. Inbound Rules.
      2. Outbound Rules.
  5. Preparing and install prerequisites on BizTalk Server 2013 R2 machine.
    1. Important considerations before set up the servers.
    2. Enable Internet Information Services.
    3. Running the BAM Portal in a 64-bit Environment.
    4. Install Windows Identity Foundation (WIF) (optional).
    5. Install Microsoft Office Excel 2013 (optional).
    6. Install Visual Studio 2013 (optional).
    7. Remove Microsoft SQL Server Express.
    8. SQL Server Considerations.
    9. Install SQL Server 2014 Client Tools.
    10. Create SQL Alias to communicate with remote SQL Server using Non-Standard Port (optional).
    11. List of ports between SQL Server and BizTalk Server (optional).
    12. Configure Firewall on BizTalk Server machine.
      1. Inbound Rules.
      2. Outbound Rules.
  6. Testing environment connectivity’s.
    1. TCPView.
    2. DTCPing.
    3. DTCTester.
    4. SQL Server 2014 Client Tools.
  7. Install and configure BizTalk Server 2013 R2 machine.
    1. Install BizTalk Server 2013 R2.
      1. Verify Your Installation.
    2. Configure BizTalk Server.
      1. Pin BizTalk Server Administration to taskbar.
    3. Validate Mail account used by BizTalk to send BAM Alerts.
    4. Install BizTalk Adapter Pack.
      1. Microsoft BizTalk Adapter Pack and Microsoft BizTalk Adapter Pack (x64).
      2. Steps to install BizTalk Adapter Pack.
      3. Add adapters to BizTalk Administration Console.
    5. Install Critical Windows Updates and BizTalk Server Cumulative Update Package.
    6. Configure BizTalk Server SQL Jobs.
      1. How to configure Backup BizTalk Server (BizTalkMgmtDb).
      2. How to configure DTA Purge and Archive (BizTalkDTADb).
      3. MessageBox_Message_Cleanup_BizTalkMsgBoxDb.
  8. Optimize the BizTalk Server 2013 R2 environment
    1. Deleting BizTalk backup files.
      1. Implementing a custom sp_DeleteBackupHistory.
      2. Implementing a Maintenance Plan to clean BizTalk Database backup’s files.
    2. Pre-allocate space and define auto-growth settings for BizTalk Server databases. 112
    3. Configure BizTalk Server Windows Services.
    4. Install and configure BizTalk Health Monitor.
      1. How to register BizTalk Health Monitor Snap-In.
      2. How to integrate BHM Snap-In into BizTalk Admin Console
    5. Install SSO Configuration Application MMC Snap-In
    6. Configure BizTalk Jobs History (Microsoft SQL Server Agent job history log).
      1. To resize the job history log based on raw size.
    7. Force Full Backup BizTalk Server (BizTalkMgmtDb) job.
    8. Managing and cleaning BizTalk Server MarkLog database tables.
    9. Configure host and Host instances.
      1. What’s is Host, Host Instances and Adapter Handlers?.
      2. Best practices to Configuring Hosts and Host Instances.
      3. How can I automate this task?.
    10. Power Mode.
    11. Consider setting the ‘text in row’ table option to boost BizTalk Server Performance.
      1. How to exploit the Text in Row table option in BizTalk Server.
    12. General network TCP settings that can impact BizTalk Server
      1. How to Disable the Scalable Networking Pack (SNP) features
      2. How to Disable Privilege Attribute Certificate (PAC)
      3. How to Check and if necessary increase the ephemeral ports and reduce the TCP re-use timeout setting

download-whitepaper

If you are interest to see other version check the following posts:

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

Last Monday I presented a session about “Microsoft Azure Logic Apps” at Microsoft WebCamp Lisbon event and I’m happy to announce that the webcast of my session is now available online in Channel 9!

Microsoft-Azure-Logic-Apps-channel9-webcast

This session was an introduction to the new Azure Integration features: Logic Apps and also a glimpse about API Apps. They are still in preview but this session attempts to address how can we get start using these new features, explain how you can use Azure Logic Apps to automate business processes without using code, demonstrating the new graphical designer and how to take advantage of different Logic App capabilities for your scenarios.

I will also explain how you can take advantages of different Azure features like Event Hub and Stream Analytics to add Insights and Telemetry to your Logic Apps through Power BI.

Microsoft-Azure-Logic-Apps-add-Insights-and-Telemetry-Logic-Apps-through-Power BI

Thanks Microsoft Portugal to organize this amazing event, it was a huge success! With over than 350 attendees, 23 speakers delivering a total of 1170 minutes of content with 24 talks (45min) + a keynote (90 min); (you can see all the session in Channel 9 here) and 510 Cloud waffles (yes there were served waffles for all the attendees Smile)

Microsoft-WebCamp-Lisbon-December-2-2015-2.jpgMicrosoft-WebCamp-Lisbon-December-2-2015.jpgMicrosoft-WebCamp-Lisbon-December-2-2015-4.jpg

Small note: This post is for the BizTalk Server and other Portuguese Community because the session is in my native language: Portuguese Smile

So what happened in 2015? Many things! But, shortly, it was a good year both personal and professional, the end of last year was crazy in terms of projects, so crazy that I didn’t had any free time to write new posts on my blog (a thing that I enjoy doing)… I even thought I had published a few posts this year (at least considerably less than last year)… SURPRISE! Despite all that I still was able to publish 27 more post than last year, in a total of 97 post!

In 2015, there were 79 new posts, growing the total archive of this blog to 482 posts.

Microsoft-WebCamp-Lisbon-December-2-2015-2

BizTalk Mapping Patterns and Best Practices is now a physical book…

Thanks to BizTalk360 (the publisher), my first book is now able as a physical print copy!! This is a book completely free for the community. A book that was announced in Oslo, Norway during the BizTalk Innovation day of 2014.

BizTalk Mapping Patterns and Best Practices” book is a 400-page recipe that offers insights on how maps work, the most common patterns in real time scenarios, and best practices for BizTalk Developers to develop effective, robust, and organized maps. The book has as technical reviewers Steef-Jan Wiggers, Nino Crudele, Michael Stephenson and José António Silva and is available for you to download at BizTalk360 website here.

printed-version-book

A year of speaking engagements…

Wow I had the opportunity to be present 13 sessions!!, has a speaker, some of them with completely different topics (TechNet Wiki, several topics about BizTalk Server and of course Logic Apps), in multiple events across Europe (UK, Belgium and Portugal) and some of them through live meetings. That indeed is my personal record so far!

Here is the complete list of speaking engagements that I had in 2015:

  • III Evento da Comunidade Porto.Data | January 22, 2015

III-Evento-Comunidade-Porto.Data-January-22-2015

  • 2 talks in TechNet Wiki Summit 2015 | March 17-18-19, 2015
  • BizTalk Summit London 2015 | April 13-14, 2015

BizTalk-Summit-London-April-13-14-2015BizTalk-Summit-London-April-13-14-2015-2

  • Microsoft MVP Showcase | April 25, 2015

Microsoft-MVP-Showcase-April-25-2015Microsoft-MVP-Showcase-April-25-2015-2

  • Global Azure Bootcamp 2015 | April 25, 2015

Global-Azure-Bootcamp-2015-April-25Global-Azure-Bootcamp-2015-April-25-2

  • BTUG.be – Integration Day 2015 | June 4th, 2015

BTUG.be-Integration-Day-2015-June-4-2015

  • 2 Talks at Integration Monday | August 31 and June 22, 2015
  • XI Porto.Data Community Meeting | September 30, 2015

XI-Porto.Data-Community-Meeting-September-30-2015

  • 2 talks in SQLSaturday#429 Porto | October 3, 2015

SQLSaturday-429-PortoSQLSaturday-429-Porto-2SQLSaturday-429-Porto-3

  • Microsoft WebCamp Lisbon | December 2, 2015

Microsoft-WebCamp-Lisbon-December-2-2015Microsoft-WebCamp-Lisbon-December-2-2015-3Microsoft-WebCamp-Lisbon-December-2-2015-4

For me is always a great honor and joy to be participating in events, either as speaker or attendee, be with old friends, meet new people and share knowledge!

And yet had the opportunity once again to attend some events like:

  • MVP Global Summit 2015

MVP-Global-Summit-2015MVP-Global-Summit-2015-2

  • A few SQLPort and Porto.Data Community events;
  • An incalculable number of internal training events at DevScope;
  • And more
My Blog is growing every year…

Very special thanks to all my reader I really appreciate the 350,000 visits to my blog, from 184 countries in the past year. That’s 40,000 more visits than last year and 150,000 more than 2013!

  • 2014: 310,000 visits, 183 countries, 52 new posts
  • 2013: 200,000 visits, 176 countries, 79 new posts
  • 2012: 170,000 visits, 171 countries, 102 new posts
  • 2011: 91,000 visits, 61 new posts

Most visitors came from The United States. India & United Kingdom were not far behind.

And even with all the speaking events that I had I still was able to write 79 new posts.

The posts that got the most views in 2015 were:

  1. BizTalk 2013 Installation and Configuration – Install and Configure BizTalk Server 2013 (Part 9) posted in May 2013
  2. BizTalk 2013 Installation and Configuration – Important considerations before set up the server (Part 1) posted in May 2013
  3. The source was not found, but some or all event logs could not be searched. Inaccessible logs: Security. posted in February 2012
  4. BizTalk 2013 Installation and Configuration – Install SQL Server 2012 (Part 7) posted in May 2013
  5. BizTalk 2013 Installation and Configuration – Installing BizTalk Adapter Pack (Part 12) posted in May 2013

However my favorite’s posts that I enjoyed writing last year was:

TechNet Wiki, BizTalk Open Source Contributions

And as has been the case in recent years, I’m BizTalk Technet Contributor were I write articles in Microsoft TechNet Wiki and BizTalk TechNet moderator. I’m also member of the TechNet Wiki Community Council and TechNet Wiki Ninja Blogger.

And many other contributions….

Besides community work…

… of course friendship, family, travelling and running were also important things as always!

  • 2015 I had the pleasure to have 3 great friends in my house/country: Steef-Jan Wiggers, Kent Weare and his wife, and Nino Crudele and is family!

Kent Weare and wifeNino-and-familyNino-and-family-2

  • Besides travelling for speaking events I was able to visit several places in Portugal (a personal choice this year) for pleasure
  • And several MVP Meetings

me-2015

Thanks for following me, for reading my blog and I promise that I will continue to share my knowledge during 2016.

Microsoft Integration MVP 2013

Microsoft Azure MVP 2016

Thanks Microsoft for another wonderful start of New Year. Once again I’m delighted to share that I was renewed, for the 6th straight year, as MVP (Microsoft Most Valuable Professional), this time after the changes that have occurred in the Microsoft MVP Program, as a Microsoft Azure MVP.

I never thought to become who I am today, it never crossed my mind… I started playing with computers when I was 5 or 6-year-old with my Timex Sinclair 2068 and the felling I had that day is still on my blood… I grow playing games and compete with my old brother, my two young cousins and some of my friends, looking back, I knew somehow that my future would be related with this area (IT, computers). Then I was lucky to find the ideal people at the right time who believed in me and that encouraged me to become what I am today, for that a huge and special thanks to Rui Barbosa and José António Silva… and I am a lucky person because I am paid to do what I love the most!

But it was only a few years ago that I decide to start to share my knowledge, largely through my blog, which began as a kind of personal notebook, it was all about having fun and a way to escape the stress of everyday life…nothing has change! But without realizing it, sharing my knowledge allowed me to grow as a person, to see the World and to meet amazing people and the most amazing friends!

My “wife” says that the computer in an extension of my personality, she met me that way, she loves me the way I am and for that reason she encourage me to become even better, thanks Fernanda for all your support!

Once again a big thanks to the MVP Team in especially to my MVP Lead Cristina Herrero and Alessandro Teglia, to all members of BizTalk and Azure Product Teams, Microsoft Portugal, all community members and special to my readers.

To my family, to the BizTalkCrew (Nino Crudele, Tord Glad Nordahl, Saravana Kumar and Steef-Jan Wiggers) and to all my coworkers at DevScope: THANKS for all the support during this last years!

It’s a big honor to be in the program and I’m looking forward to another great year. And remember Enjoy life, follow your dreams and most importantly have fun!

WP_20160101_21_59_48_ProWP_20151206_16_08_37_Pro

(In the right: my family celebrating; in the left: me and Fernanda)

In my native language (Portuguese):

Obrigado Microsoft para outro maravilhoso início de Ano Novo. Estou muito feliz por poder partilhar com todos vocês que fui nomeado Microsoft Most Valuable Professional (MVP) 2016|

Esta é a sexta vez que recebo este prémio e como é normal nestas ocasiões, gostaria de agradecer a todos os leitores do meu blog, amigos, a todos os membros da comunidade. Também gostaria de agradecer a minha MVP Lead Cristina Herrero, ao Alessandro Teglia, a todas as pessoas da Microsoft em especial à equipa de produto do BizTalk e Azure, Microsoft Portugal, a todos os meus colegas Microsoft Integration MVP’s e a todos os MVP’s Portugueses.

Eu também gostaria de fazer um agradecimento muito especial a minha há minha família e a minha linda namorada Fernanda por todo o seu suporte neste ultimo ano, ao membros do BizTalkCrew (Nino Crudele, Tord Glad Nordahl, Saravana Kumar e Steef-Jan Wiggers) e, finalmente, a todos os meus colegas de trabalho na DevScope, dos quais eu gostaria de destacar este ano o Rui Quintino e o João Sousa que se tornaram este ano MVP’s pela primeira vez! Parabéns!

É uma grande honra estar no programa e espero continuar a contribuir para a comunidade BizTalk, e integração no geral, e a merecer o reconhecimento.

I been reviewing Packt Publishing BizTalk books for a while and from time to time they keep me posted for special offers or invite me to write about them to spread the word in the community… And with more than 3000 eBooks and video courses available for just $5! I think this is one of that offer you cannot miss!

$5-promo

And you will find a few great BizTalk books… I can say that because I have them ALL Smile

  • (MCTS) Microsoft BizTalk Server (70-595) Certification and Assessment Guide: Second Edition
  • (MCTS): Microsoft BizTalk Server 2010 (70-595) Certification Guide
  • BizTalk Server 2010 Cookbook
  • Microsoft BizTalk Server 2010 Patterns
  • Microsoft BizTalk 2010: Line of Business Systems Integration
  • SOA Patterns with BizTalk Server 2013 and Microsoft Azure – Second Edition
  • And many more

BizTalk-books-packt

This seasonal sale will only be running until January 6th January 2016 – you can get as many eBooks as you like in the offer, so head on over to www.packtpub.com and grab your copies today.

Merry Christmas & Happy New Year 2016

Posted: December 24, 2015 in Other

And one more time we wretched to that special time of the year! And once again my sincere wishes for a Merry Christmas and a Happy New Year to all my readers, friends, coworkers (amazing guys at DevScope), Microsoft BizTalk Community, all the Portuguese Communities, my MVP “family” and of course to my family.

Thanks in advance for all the support and encouragement given throughout this year. It was an incredible year for me, on both a personal and professional level and hope that the next will be a year filled with new articles, I promise that I will continue to share knowledge hoping that they can help someone.

The Microsoft Integration stack is full of new exciting things both on premise and in the cloud (Logic Apps, API Apps and PowerApps and so on) so we are expecting great challenges for 2016… so stay tune!

Hope you have a beautiful holiday period with your near and dear ones.

Happy holidays!

postal-natal-sandro-13

And for the first time in my native language (Portuguese):

A todos os meus leitores, amigos, família e para todas as comunidades, os meus sinceros votos de um Bom Natal, um Feliz Ano Novo e um 2016 cheio de bons negócios, muita saúde, felicidade e claro muitas integrações.

Desde já obrigado por todo o apoio e incentivo dado ao longo deste ano e que o próximo seja um ano recheado de novos artigos, da minha parte fica a promessa que irei continuar a partilhar conhecimento na esperança de poder sempre ajudar alguém.