The file minimal.json contains:
{
"data": {
"labels": [
"GERMAN AMERICAN BANK",
"JOHNSON BANK",
"WASHINGTON TRUST BANK"
],
"datasets": [
{
"data": [
{
"y": 43.84,
"x": 51
},
{
"y": 47.02,
"x": 12
},
{
"y": 58.21,
"x": 53
}
],
"label": "data"
}
]
},
"options": {
"title": {
"text": "Banks",
"display": true
},
"scales": {
},
"plugins": {
"datalabels": {
"formatter": function(value, context) { var idx = context.dataIndex; return context.chart.data.labels[idx]; },
"display": true
}
}
},
"type": "scatter"
}
If I execute the following at a console:
@{ chart = Get-Content C:\temp\minimal.json -Raw } | ConvertTo-Json -Depth 100
The console appears to hang. It is unresponsive to C-c.
Is this a bug in ConvertTo-Json?
Any suggestions on how to get this example to work?
tl;dr
Your problem is specific to Windows PowerShell (it no longer affects PowerShell (Core) 7+).
A solution that works in both editions is to cast the Get-Content -Raw … call to [string]:
@{ chart = [string] (Get-Content C:\temp\minimal.json -Raw) } |
ConvertTo-Json -Depth 100
Note: -Depth 100 is not required in this case, because the default depth, 2, is sufficient to serialize your input hashtable (the content of the chart entry value, due to being a string, is irrelevant with respect to the recursion depth - leaving the undesired Windows PowerShell behavior discussed below aside).
However, in general it's worth paying attention to whether a -Depth argument is needed - see this post.
Get-Content, in both PowerShell editions, decorates its [string] output objects with ETS (Extended Type System) properties.
PSChildName, PSDrive, PSParentPath, PSPath, PSProvider, and ReadCount, and you can discover them with Get-Content C:\temp\minimal.json -Raw | Get-Member -Type NoteProperty).In Windows PowerShell only, these properties are included when these output objects are serialized via ConvertTo-Json.[1]
Serializing arbitrary .NET objects with -Depth 100 can result in excessive amounts of data getting serialized and even potentially infinite loops, depending on the nature of the object - this is what you saw, due to the ETS properties being included in the serialization.
Casting the Get-Content -Raw … call to [string] implicitly discards the ETS properties, resulting in an undecorated [string] instance that serializes as just its text, and thereby bypasses the problem.
[1] PR #15665, which took effect in PowerShell (Core) 7.2., now intentionally excludes ETS properties of types [string] and [datetime], specifically.
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