I´m writing a script in powershell 2.0 and an upgrade to 3.0 or higher is not possible right now. In this script I try to serialize some data to JSON with the code from this link (PowerShell 2.0 ConvertFrom-Json and ConvertTo-Json implementation):
function ConvertTo-Json20([object] $item){
add-type -assembly system.web.extensions
$ps_js=new-object system.web.script.serialization.javascriptSerializer
return $ps_js.Serialize($item)
}
My problem is that I somehow get a circular reference and I really don´t know why. I set up a litte piece of test data and the structure looks in powershell like this:
$testRoot = @{
"id" = "1"
"children" = @(
@{
"id" = "2"
"children" = @(
@{
"id" = "2";
};
@{
"id" = "3";
}
);
};
@{
"id" = "4"
"children" = @(
@{
"id" = "5";
}
);
}
)
}
I know it looks junky, but I just need it in this format.
The structures I need to serialize have a few more layers, so even more "children" and there is the point where it gets strange.
When I try this:
ConvertTo-Json20 $testRoot
everything works fine. The structure gets parsed like this:
{
"id":"1",
"children":[
{
"id":"2",
"children":[
{
"id":"2"
},
{
"id":"3"
}
]
},
{
"id":"4",
"children":[
{
"id":"5"
}
]
}
]
}
But now comes the problem. As mentioned the structure has more layers, so I try this which just sets the data in an array.
ConvertTo-Json20 @($testRoot)
But it does not work I just get an error message saying:
Exception in method "Serialize" with 1 argument(s):
"While serializing an object of type "System.Management.Automation.PSParameterizedProperty" a circular reference was discovered."
At C:\Users\a38732\Desktop\Temp.ps1:34 symbol:28
+ return $ps_js.Serialize <<<< ($item)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
(I translated the error message from german, so there might be some words different in the english version...)
One problem is the use of the JavaScriptSerializer
class itself. As of this date the documentation itself concedes it should not be used to serialize nor deserialize JSON. To quote:
Json.NET should be used serialization and deserialization.
If you're able to use third-party libraries like Json.NET, here's a simple function that does what you need given the data structure in the OP:
function ConvertTo-JsonNet {
[CmdletBinding()]
param(
[Parameter(Mandatory)] $object,
[Parameter(Mandatory)] [string]$jsonNetPath,
[switch]$indent,
[switch]$preserveReferencesHandling
)
Add-Type -Path $jsonNetPath;
$formatting = if ($indent.IsPresent) { [Newtonsoft.Json.Formatting]::Indented; }
else { [Newtonsoft.Json.Formatting]::None; }
$settings = New-Object Newtonsoft.Json.JsonSerializerSettings;
if ($preserveReferencesHandling.IsPresent) {
$settings.PreserveReferencesHandling = [Newtonsoft.Json.PreserveReferencesHandling]::Objects;
}
[Newtonsoft.Json.JsonConvert]::SerializeObject($object, $formatting, $settings);
}
Simple usage, assuming Newtonsoft.Json.dll
is in the same directory as your script:
$dllPath = Join-Path $PSScriptRoot 'Newtonsoft.Json.dll';
ConvertTo-JsonNet @($testRoot) $dllPath;
Output:
[{"id":"1","children":[{"id":"2","children":[{"id":"2"},{"id":"3"}]},{"id":"4","children":[{"id":"5"}]}]}]
You can manually download the .dll from the nuget package project site. It has a .nupkg
file extension, but it's a zipped archive, so rename the extension to .zip
and you're set. In the lib
sub-directory there are .dll files for .NET versions from 2.0 through 4.5.
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