Forum Discussion
Problem outputting hashtable to JSON
I have 2 hashtables that I want to convert to JSON. The $Header hashtable doesn't seem to work as expected but the $Body hashtable does work and I see the data presented in JSON.
PoSH:
#Issue with $Headers hashtable
$Headers = [ordered]@{
"FTX-KEY" = $API;
"FTX-TS" = $FTX_TS;
"FTX-SIGN" = $Signature1;
"FTX_SubAccount" = $FTX_SubAccount} | ConvertTo-JSON -Compress # piping here Triggers the error
#$Headers = $Headers | ConvertTo-JSON -Compress #Triggers the error
$Headers # Error shown in console
# The following Body is presented as JSON as expected
$Body = [ordered]@{
"market" = $Market;
"price" = $Price2;
"type" = $OrderType;
"size" = $Size} | ConvertTo-JSON -Compress
$Body # data presented as JSON as expected
The error returned is: "Invoke-RestMethod : Cannot bind parameter 'Headers'. Cannot convert the "{"FTX-KEY":"fDaVsj2YXZkuWxst_lLkD7s6y_kw7AzxDwHQzTCk","FTX-TS":1653503194001,"FTX-SIGN":"JSQUX5gZax4LU1LR4bdWj1AeFWOpWhfQ9cDxdS2wqmM=","FTX_SubAccount":"Trade%20-1"}" value of type "System.String" to type "System.Collections.IDictionary"."
As you can see in the code comments, I have tried the same method of piping to ConvertTo-JSON as with the $Body, but it is not working and I am unsure why.
I have tried removing the entries within the hashtable and replaced them with e.g. "test" = $test and the same error occurs. I've tried single and double quotes too, despite double quotes working in the $body hashtable.
Any ideas?
p.s. I changed the API key in the error ๐
5 Replies
- DeltaworksCopper ContributorHi Porkopops, would you mind sharing the code of how you create the FTX signature in Powershell.
I keep getting a Signature incorrect error - LainRobertsonSilver Contributor
You don't want the piped call to ConvertTo-Json for the header. The body can be whatever you like but not the header.
As the error as well as the Microsoft documentation state, it's expecting either an explicit IDictionary type or a type it can implicitly convert to one, and [System.String] - which is what you get from calling ConvertTo-Json - is not such a type.
Invoke-RestMethod (Microsoft.PowerShell.Utility) - PowerShell | Microsoft Docs
Simply remove the trailing "| ConvertTo-Json -Compress" and you'll be back in business.
Cheers,
Lain
- porkopopsCopper ContributorLainRobertson Many thanks for your reply.
Is it valid to send a header as a hashtable rather than JSON when using Invoke-RestMethod?- LainRobertsonSilver Contributor
I think you're getting confused with the content type of the body versus the header.
As the Microsoft Docs link above states, the header has to be compatible with the IDictionary interface.
IDictionary Interface (System.Collections) | Microsoft Docs
If you expand the "Derived" link in that article, you can see that PowerShell's [hashtable] (full type name is [System.Collections.Hashtable]) and [ordered] (full type name is [System.Collections.Specialized.OrderedDictionary]) are both in that list, meaning they are compatible with the "-Headers" parameter, as per the Microsoft Docs article linked above for Invoke-RestMethod.
The "-Body" parameter is a completely different story. -Body can be any type you like (more or less), including JSON.
Again, referring back to the Invoke-RestMethod, if you look at the specification for the "-Body" parameter, you will see it's listed as "<Object>" ([System.Object]), which is the base class for all object types.
So, in short, we have:
-Headers IDictionary -Body Object Now, as I mentioned before, the data type produced from ConvertTo-Json is String [Systm.String] which is not compatible with IDictionary.
This is precisely what your error message is telling you. It is saying, "hey, I cannot convert a System.String into System.Collections.IDictionary!" (which means any of those compatible types listed under "Derived", as mentioned earlier.)
So, this is the detailed explanation for your question above.
The short answer is this:
Yes, it is valid to send the header using a [hashtable] (or [ordered] - or any other collection type from the Derived list.)
In fact, it's more than "valid", it's required that you use a hash table (in contrast to a string, which will not work, as you're already seeing), as per the specification within the Microsoft Docs for Invoke-RestMethod.
So, get rid of the "| ConvertTo-Json" statements from your "$Header" lines and everything will work the way you anticipated it would.
Here is your code adjusted to exclude the call to ConvertTo-Json on the $Header variable.
# $Headers hashtable $Headers = [ordered]@{ "FTX-KEY" = $API; "FTX-TS" = $FTX_TS; "FTX-SIGN" = $Signature1; "FTX_SubAccount" = $FTX_SubAccount} $Headers # The following Body is presented as JSON as expected $Body = [ordered]@{ "market" = $Market; "price" = $Price2; "type" = $OrderType; "size" = $Size} | ConvertTo-JSON -Compress $Body # data presented as JSON as expectedCheers,
Lain