Powershell Core deserializes numbers in JSON as Int64 vs Windows Powershell which does it as Int32
See original GitHub issueThis is actually a copy of the StackOverflow issue with the same name from @Mark: Powershell Core deserializes numbers in JSON as Int64 vs Windows Powershell which does it as Int32
Steps to reproduce
$a = "1" | ConvertFrom-Json
(@{ $a = 2 }).1
Expected behavior
Return 2
(just like Windows PowerShell 5)
Actual behavior
Returns nothing (because the actual key is of type [Int64]
and the key “.1
” of type [Int32]
)
I am not sure whether this can be called a bug or is “by design” but my expectation (from a dynamically typed language as PowerShell Core) is that a Json number (less then [int]::MaxValue
) should default to an [Int32]
type, just like:
$a = 1
$a.GetType().Name
Int32
Workarround
Recast the number:
$a = "1" | ConvertFrom-Json
$a = 0 + "$a"
(@{ $a = 2 }).1
2
related:
- #9207 convertto-json bigint is not properly serialized
- Make Newtonsoft JsonConvert Default to Int32 Rather Than Int64
Environment data
Name Value
---- -----
PSVersion 7.1.0
PSEdition Core
GitCommitId 7.1.0
OS Microsoft Windows 10.0.19042
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
Issue Analytics
- State:
- Created 3 years ago
- Reactions:2
- Comments:6 (3 by maintainers)
Top Results From Across the Web
Powershell Core deserializes numbers in JSON as Int64 vs ...
Windows PowerShell uses a custom implementation, whereas PowerShell [Core] v6+, as of v7.1, uses the Json.NET library behind the scenes; see ...
Read more >Invoke-RestMethod - PowerShell
The Invoke-RestMethod cmdlet sends HTTP and HTTPS requests to Representational State Transfer (REST) web services that return richly structured data.
Read more >Understanding Numbers in PowerShell - Scripting Blog
There are actually three numeric types that Windows PowerShell uses: Decimal types; Integral types; Floating-point types. Decimal types.
Read more >ConvertTo-Json - PowerShell
The ConvertTo-Json cmdlet converts any .NET object to a string in JavaScript Object Notation (JSON) format. The properties are converted to field names, ......
Read more >JavaScriptSerializer Class (System.Web.Script.Serialization)
Therefore, you can use the class when you want to work with JavaScript Object Notation (JSON) in managed code. To serialize an object,...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
The problem is that JSON is an invariably “lossy” serialization format with .NET types as the input. You lose the specific number types, as any number in JSON becomes that abstraction: a JSON primitive of kind
Number
. Similarly, JSON has no[char]
type, onlyString
.Therefore, no one should expect a round trip to work.
However, it is reasonable to expect from-JSON conversion to expect PowerShell-typical behavior, which to me means performing the automatic type-widening as needed, the same way that (non-type-letter-suffixed) number literals in PowerShell source code employ, which means:
[int]
as the smallest type ->[long]
->[decimal]
->[double]
.(On a related note: going from
[decimal]
to[bigint]
before going to[double]
in number-literal parsing would make sense, to avoid quiet loss of accuracy - see #13212; by contrast,ConvertFrom-Json
in PS Core currently skips the[decimal]
step and goes straight from[long]
to[bigint]
- see https://github.com/PowerShell/PowerShell/issues/9207#issuecomment-573992565) - whereas Windows PowerShell tops out at[double]
beyond[decimal]
, and never uses[bigint]
.Yes, as implied by a quote of the author of the Json.NET library underlying the current
ConvertFrom-Json
from the SO answer that @iRon7 links to in the OP:The use of
may in some cases require an adaptation of the code depending on the version of powershell.
Example :
If I have to search for a key, from a cast of a string, the code differs.
Shouldn’t this post be marked as ‘Breaking change’ ?