Wednesday, November 27, 2019

How to specify BindingRedirects in Azure functions app settings via ARM template in automatic provisioning scenarios

If you face with famous problem with Newtonsoft.Json version mismatch in Azure functions (when Azure functions SDK requires one specific version and e.g. OfficeDevPnP requires other – you get error in runtime that Newtonsoft.Json.dll of version x.x.x.x is not found). There is solution for this issue posted here: Performing a binding redirect in Azure Functions. With this solution we have to add new app setting for Azure function which is string representation of JSON array:

{
    "BindingRedirects": "[ { \"ShortName\": \"Newtonsoft.Json\", \"RedirectToVersion\": \"11.0.0.0\", \"PublicKeyToken\": \"30ad4fe6b2a6aeed\" } ]"
}

It works but if you use automatic provision of Azure functions using template json file (see Azure Resource Manager template functions) and will want to specify it there like this:

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "BindingRedirects": {
            "type": "string",
            "defaultValue": "[{ \"ShortName\": \"Newtonsoft.Json\", \"RedirectToVersion\": \"12.0.0.0\", \"PublicKeyToken\": \"30ad4fe6b2a6aeed\" }]"
        }
    }
}

you will see the following error:

Error occured when try to create Function app (error code 1):
Error: Code=InvalidTemplate; Message=Deployment template language expression evaluation failed: 'The language expression '{ "ShortName": "Newtonsoft.Json", "RedirectToVersion": "12.0.0.0", "PublicKeyToken": "30ad4fe6b2a6aeed" }
' is not valid: the string character '{' at position '0' is not expected.'. Please see https://aka.ms/arm-template-expressions for usage details.

The problem here is that BindingRedirects app setting use square brackets which at the same time are used by ARM template engine for specifying calculated values. Solution for this problem is to escape square brackets by double them i.e. instead of [ use [[ and instead of ] use ]]. Final version will look like this:

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "BindingRedirects": {
            "type": "string",
            "defaultValue": "[[{ \"ShortName\": \"Newtonsoft.Json\", \"RedirectToVersion\": \"12.0.0.0\", \"PublicKeyToken\": \"30ad4fe6b2a6aeed\" }]]"
        }
    }
}

After that provision of ARM template for Azure functions will go well.

No comments:

Post a Comment