question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

ArmDeploymentPropertiesExtended.Outputs does not return valid JSON

See original GitHub issue

I’m trying to collect the outputs from an ARM template using the Outputs property of ArmDeploymentPropertiesExtended.

For example:

var depop = rg.GetArmDeployments().CreateOrUpdate(Azure.WaitUntil.Completed, "MyDeployment", deploymentContent);
var outputs = depop.Value.Data.Properties.Outputs;
var credentials = outputs.ToObjectFromJson<DeploymentCredentials>();

Where the outputs section of my ARM template contains something like this:

"outputs": {
    "username": {
      "value": "[list(resourceId('Microsoft.Web/sites/config', variables('function_app_name'), 'publishingcredentials'), '2016-08-01').properties.publishingUserName]",
      "type": "string"
    },
    "password": {
      "value": "[list(resourceId('Microsoft.Web/sites/config', variables('function_app_name'), 'publishingcredentials'), '2016-08-01').properties.publishingPassword]",
      "type": "string"
    }
  }

If I inspect the BinaryData object returned, it appears to contain a username and password that match what I can see in the Azure portal. A promising start. Unfortunately, on closer inspection, the BinaryData contents is not quite valid JSON:

{
	{
        "username": {
            "type": "String",
            "value": "$someValueHere"
        },
        "password": {
            "type": "String",
            "value": "AsIfImGoingToShareThaat_DeadBeef_0123456789"
        }
    }
}

This is almost valid JSON, except for the extra pair of curly braces. This can be checked at (for instance) jsonlint.com, which complains with the following message:

Error: Parse error on line 1:
{	{		"username": {		
--^
Expecting 'STRING', '}', got '{'

Unfortunately, this is enough to break the JSON deserialiser, so that when we call outputs.ToObjectFromJson<DeploymentCredentials>() we get an empty instance of our class, without the values from the response.

Issue Analytics

  • State:open
  • Created a year ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
tdwrightcommented, Aug 12, 2022

Hi @Yao725. Thanks for taking a look. Case sensitivity is a good guess, but I think I can rule it out. I’m using JsonProperty attributes that match the casing of the raw JSON names. Since I can get it to work (see below) without further tweaks to the JsonSerializerOptions, I think we can rule this out.

I’m pretty sure the problem is that the returned JSON string contains a JSON object nested within another JSON object, without being in an array or having a key. This is not valid per the JSON specification (friendly | RFC) and causes errors in every validator I’ve tried. I actually first noticed this when trying to (lazily) generate the classes with quicktype.

As I said in my 2nd comment above, removing the outer pair of braces makes the JSON valid and allows it to be deserialised. For anyone else who stumbles across this problem, here’s the code I used to fix it:

private static DeploymentCredentials ExtractCredentialsFromDeployment(ArmOperation<ArmDeploymentResource> depop)
{
	var outputs = depop.Value.Data.Properties.Outputs.ToString().Trim();

	var regex = new Regex(@"\{(.+)\}");
	var regexMatches = regex.Matches(outputs);
	var output_contents = regexMatches[0].Value;

	var credentials = JsonConvert.DeserializeObject<DeploymentCredentials>(output_contents);
	return credentials;
}
0reactions
Yao725commented, Aug 12, 2022

Hi @tdwright, I tested this method and it worked as expected. One possible reason that you can’t deserialize the outputs might be that ToObjectFromJson method has a default JsonSerializerOptions which set the PropertyNameCaseInsensitive to false. So could you double check if the properties’ name in DeploymentCredentials could match the response in case sensitive or you can try this way to see if the deserialization can work:

JsonSerializerOptions options = new JsonSerializerOptions
{
    PropertyNameCaseInsensitive = true
};
Sample sample= deployment.Data.Properties.Outputs.ToObjectFromJson<Sample>(options );
Read more comments on GitHub >

github_iconTop Results From Across the Web

Quickstart: Troubleshoot ARM template JSON deployments
This quickstart describes how to troubleshoot Azure Resource Manager template (ARM template) JSON deployment errors.
Read more >
ArmDeploymentPropertiesExten...
Key/value pairs that represent deployment output. To assign an object to this property use FromObjectAsJson<T>(T, JsonSerializerOptions).
Read more >
How do I return JSON from an Azure Function
Here's a full example of an Azure function returning a properly formatted JSON object instead of XML: #r "Newtonsoft.Json" using System.
Read more >
Azure Pipelines gate failing, SN API not returning JSON
We have setup the Azure DevOps and SN integration. Azure DevOps is complaining that the SN API is not returning JSON.
Read more >
vcsa-deploy.exe JSON syntax validator broken on vC...
I have a PowerShell script that I use to deploy vCSA. It generates the JSON template file for the vcsa-deploy.exe to use as...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found