I need to HttpPost a Json-body to a ASP.NET Core Web Api endpoint (controller) using a PowerShell script.
$CurrentWindowsIdentity = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
$CurrentPrincipalName = $CurrentWindowsIdentity.Identity.Name
# Build JSON payload
$JsonString = @"
{
"CurrentPrincipalName":"$CurrentPrincipalName"
}
"@
$response = Invoke-RestMethod -Uri "https://webapiendpoint.tld/api/somecontroller" -Method Post -Body $JsonString -ContentType "application/json"
Since the value of the variable $CurrentPrincipalName can be domain\username, the json get's invalid because of the backslash, which is not properly escaped.
Error in the log of the web api:
JSON input formatter threw an exception: 'C' is an invalid escapable character within a JSON string. The string should be correctly escaped. Path: $.CurrentPrincipalName | LineNumber: 15 | BytePositionInLine: 36.
System.Text.Json.JsonException: 'C' is an invalid escapable character within a JSON string. The string should be correctly escaped. Path: $.CurrentPrincipalName
How can i make sure that when creating a json string and adding variables - whose values of course can not be controlled - the json string gets properly escaped?
i also tried ConvertTo-Json like:
$JsonConverted = $JsonString | ConvertTo-Json
and then HttpPost that object, but that was even worse:
JSON input formatter threw an exception: The JSON value could not be converted to solutionname.model. Path: $ | LineNumber: 0 | BytePositionInLine: 758.
The robust way to create JSON text is to construct your data as a hash table (@{ ... }) or custom object ( [pscustomobject] @{ ... }) first and pipe to ConvertTo-Json:
$JsonString = @{
CurrentPrincipalName = $CurrentPrincipalName
} | ConvertTo-Json
That way, PowerShell performs any necessary escaping of values for you, notably including doubling the literal \ character in your $CurrentPrincipalName value to ensure that it is treated as a literal.
Note:
Depending on how deeply nested the hashtable is, you may have to add a -Depth argument to the ConvertTo-Json call to prevent more data from getting truncated - see this post for more information.
If you have multiple properties and want to preserve their definition order in the JSON representation, use an ordered hash table ([ordered] @{ ... }) or a custom object.
In cases where the resulting JSON string is to be passed to an external program, in Windows PowerShell and in PowerShell (Core) up to v7.2.x you unfortunately have to \-escape all " characters - see this answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With