Search code examples
jsonbiztalkbiztalk-2020

BizTalk jsonencodes null-boolean to empty string


Our Dynamics CRM system exports an entity that contains boolean elements. The values the element can have are: true, false, and null. The null value is used if it's not known if the element is secret or not. For example Dynamics will export the following xml:

<SecretPhone>true</SecretPhone>
<SecretEmail>false</SecretEmail>
<SecretAddress i:nil = "true">

Then when BizTalk sends it to a topic in Azure Servicebus using SB-messaging adapter with a jsonencoder pipeline the result is as follows:

{
  "SecretPhone": true,
  "SecretEmail": false,
  "SecretAddress": ""
}

I would have expected the null boolean value to be null instead of empty string:

{
  "SecretPhone": true,
  "SecretEmail": false,
  "SecretAddress": null
}

I have tried mapping to target xml in the following ways

<SecretAddress i:nil = "true" /> maps to <SecretAddress />

That results in the empty string in json. (SecretAddress: "")

I also tried to map it like this:

<SecretAddress i:nil = "true"> maps to <SecretAddress i:nil = "true" />

but that results in even stranger json

    "SecretAddress": {
      "@nil": "true"
    },

We are using BizTalk 2020 CU3. Sandro Pereira has built a custom JsonEncoder pipeline component that can override the built in JsonEncoder so maybe I need to use that. My workaround now is to map null boolean value to false but that alters the data being sent to the target system.

Any other ways to jsonencode a null xml boolean value to a null json value?


Solution

  • It took some time due to Christmas vacations and then waiting for feedback from the testers. After having read @Dijkgraaf answer to the question he linked to in the comment above, I managed to solve the problem like this:

    All boolean elements in target schema have nillable attribute set to true. Then in the BizTalk map I used a scripting functiod with inline xslt to map the boolean elements:

    <xsl:variable name="boolEmail" select="/SecretEmail"/>
    <xsl:choose>
        <xsl:when test="$boolEmail=''">
                <SecretEmail/>
        </xsl:when>
        <xsl:otherwise>
                <SecretEmail>
                  <xsl:value-of select="$boolEmail" /> 
                </SecretEmail>
        </xsl:otherwise>
    </xsl:choose>
    

    With this I now get true, false and null json values in target message.