使用javascriptSerializer在powershell 2.0中使用Json循环引用

前端之家收集整理的这篇文章主要介绍了使用javascriptSerializer在powershell 2.0中使用Json循环引用前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在power shell 2.0中编写了一个脚本,目前无法升级到3.0或更高版本.在这个脚本中,我尝试使用此链接中的代码将一些数据序列化为 JSON( 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)
}

我的问题是我以某种方式获得循环引用,我真的不知道为什么.我设置了一小段测试数据,结构在powershell中看起来像这样:

$testRoot = @{
    "id" = "1"
    "children" = @( 
        @{
            "id" = "2"
            "children" = @( 
                @{
                    "id" = "2";
                };
                @{
                    "id" = "3";
                }
            );
        };
        @{
            "id" = "4"
            "children" = @( 
                @{
                    "id" = "5";
                }
            );
        }
    )
}

我知道它看起来很垃圾,但我只需要这种格式.

我需要序列化的结构有更多的层,所以更多的“孩子”,并有它变得奇怪的点.

当我尝试这个:

ConvertTo-Json20 $testRoot

一切正常.结构被解析如下:

{
   "id":"1","children":[
        {
            "id":"2","children":[
               {
                   "id":"2"
               },{
                   "id":"3"
               }
            ]
        },{
            "id":"4","children":[
               {
                   "id":"5"
               }
            ]
        }
   ]
}

但现在出现了问题.如上所述,结构有更多的层,所以我尝试这只是在数组中设置数据.

ConvertTo-Json20 @($testRoot)

但它不起作用我只是收到一条错误消息:

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

(我翻译了德语的错误信息,所以在英文版本中可能会有一些不同的词……)

解决方法

一个问题是使用JavaScriptSerializer类本身.截至此日期为 documentation itself concedes it should not be used to serialize nor deserialize JSON.报价:

07001 should be used serialization and deserialization.

如果您能够使用像Json.NET这样的第三方库,这里有一个简单的函数,可以根据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);
}

简单的用法,假设Newtonsoft.Json.dll与您的脚本位于同一目录中:

$dllPath = Join-Path $PSScriptRoot 'Newtonsoft.Json.dll';
ConvertTo-JsonNet @($testRoot) $dllPath;

输出

[{"id":"1","children":[{"id":"2","children":[{"id":"2"},{"id":"3"}]},{"id":"4","children":[{"id":"5"}]}]}]

您可以从nuget package project site手动下载.dll.它具有.nupkg文件扩展名,但它是一个压缩存档,因此将扩展名重命名为.zip并进行设置.在lib子目录中,存在从2.0到4.5的.NET版本的.dll文件.

猜你在找的JavaScript相关文章