Home > Enterprise >  PowerShell - how to escape {} in JSON string for a REST call
PowerShell - how to escape {} in JSON string for a REST call

Time:10-21

I'm reading an HTML file and need to pass it as a string parameter to a JSON call. The HTML has curly braces in it for css/styles. I was looking at this question, but mine is more around JSON special characters where that one was other escape characters. The file may also have [] characters.

$HtmlFromFile2 = @"
<html>
    <style type="text/css">.LetterList {font-family:"arial"}</style>
    <body>
        To [firstname]:
        This is a normal body with special JSON characters. 
    </body>
</html>
"@
$HtmlFromFile2Stripped = $HtmlFromFile2.Replace("`r", "").Replace("`n", "").Replace("`t","") 
#$HtmlFromFileFixed = % { [System.Text.RegularExpressions.Regex]::Unescape($HtmlFromFile2Stripped) }
$HtmlFromFileFixed = $HtmlFromFile2Stripped.Replace("{","\{").Replace("}","\}")

Write-Host "After RegEx Fix"
Write-Host $HtmlFromFileFixed 

$templateID = "Test_Temp7"


$body = @"
{   "uuid": "$templateID",
    "subject": "My Email Subject",
    "body": "$HtmlFromFileFixed"
}
"@

# This also tests if our JSON is "well-formed", on extra or missing commas, braces, brackets, etc... 
$bodyJSON = ConvertFrom-Json $body 

# Write-Host $body

$params = @{
    Uri         = 'https://stage-tms.demo.com/templates/email'
    Headers     = $headers
    Method      = 'POST'
    Body        = "$body"
    ContentType = 'application/json'
}

#Invoke-RestMethod @params

I use the Convert-FromJSON as test. When that works, then usually the Invoke-RestMethod will work. When the Convert-FromJSON fails, the Invoke-RestMethod will come back with http statsu=400 and statusDescription="Bad Request".

Current Errors:

ConvertFrom-Json : Invalid object passed in, ':' or '}' expected. (137): {   "uuid": "FEMAImport_Home_Test_Temp7",
    "subject": "SBA Disaster Loan Assistance TestText",
    "body": "<html>    <style type="text/css">.sbaLetterList \{font-family:"arial"\}</style><body>    This is a 
normal body with special JSON characters. </body></html>"
}
At C:\Scripts\TestJSONEscapeBraces.ps1:38 char:13
  $bodyJSON = ConvertFrom-Json $body
              ~~~~~~~~~~~~~~~~~~~~~~
      CategoryInfo          : NotSpecified: (:) [ConvertFrom-Json], ArgumentException
      FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.ConvertFromJsonCommand

Update 1: I did some more tests. I'm ending up with too may permutations of what works and what doesn't work. I can't include the entire HTML file I'm using; I need a technique to isolate errors and identify them. I was hoping ConvertFrom-JSON would do that for me.

From below, you can see different files I'm trying. The first one (the real file and the larger one fails both on the ConvertFrom-JSON and the REST/Post. The other two are now working.

 $HtmlBodyFilename = "$PSScriptRoot\Emailbody_Home.html" 
#$HtmlBodyFilename = "$PSScriptRoot\Emailbody_Home_SimpleTest.html" 
#$HtmlBodyFilename = "$PSScriptRoot\Emailbody_Home_SimpleTestWithBraces.html" 
    $HtmlFromFile = Get-Content $HtmlBodyFilename -Raw   #the -Raw option gets a string instead of an array of lins 
    $HtmlFromFileStripped = $HtmlFromFile.Replace("`r", "").Replace("`n", "").Replace("`t","") 

I'm now able to read and process a small simple test file with curly braces in it. But when I point to the real HTML file on disk, I get errors, and don't know how to isolate it. I was probably assuming it was the curly brace.

If I use the ConvertFrom-JSON and the real HTML file, I get: ConvertFrom-Json : Invalid object passed in, ':' or '}' expected. (143): { "uuid": "FEMAImport_HomeFile_Test_Temp3", "subject": etc...

Now, if I remove the "ConvertFrom-JSON" and use the real HTML File, I get this error from the SOAP request: "The request was aborted: The connection was closed unexpectedly." Of course one difference is that the file is much bigger, about 83KB.

Before now, I have been getting a lot of 400 "Bad Request" errors, which is a useless error. I need to know what is wrong with the request.

CodePudding user response:

Let Powershell do all the work for you and don't build the JSON string yourself, use an object:

$body = ConvertTo-Json @{
    uuid = $templateID
    subject = "My Email Subject"
    body = Get-Content $HtmlBodyFilename -Raw
}

All special characters will be escaped automatically.

Credits to @Hazrelle, of course you don't even have to convert anything in this case, as Invoke-WebRequest will do that for you:

$params = @{
    Uri         = 'https://stage-tms.demo.com/templates/email'
    Headers     = $headers
    Method      = 'POST'
    Body        = @{
        uuid = $templateID
        subject = "My Email Subject"
        body = Get-Content $HtmlBodyFilename -Raw
    }
    ContentType = 'application/json'
}

CodePudding user response:

You even don't need to convert anything to Json. Invoke-WebRequest will do it.

$body = @{   
    uuid: $templateID,
    subject: "My Email Subject",
    body: $HtmlFromFileFixed
}
Invoke-WebRequest ... -Body $body
  • Related