【问题标题】:PowerShell v2 Converts Dictionary to Array when returned from a function从函数返回时,PowerShell v2 将字典转换为数组
【发布时间】:2015-10-01 12:26:40
【问题描述】:

首先,我必须使用 PowerShell v2,因为这是默认安装在 Windows 7 上的。我想做的事情是使用 PowerShell v4 以及可能的 PowerShell v3 开箱即用。

我想从文件中读取一个 JSON 对象并将其用作我的脚本中的对象。 PowerShell v2 没有 ConvertFrom-Json 方法,所以我编写了自己的实现,我希望拥有相同的功能:

function ConvertFrom-Json
{
    param(
        [Parameter(ValueFromPipeline=$true)]
        [string]$json
    )
        [System.Reflection.Assembly]::LoadWithPartialName("System.Web.Extensions")
    $ser = New-Object System.Web.Script.Serialization.JavaScriptSerializer
    $obj = $ser.DeserializeObject($json)

    Write-Host $obj.GetType()

    return $obj
}        

我这样称呼这个函数:

$configObj =  (Get-Content $configFile) -join "`n" | ConvertFrom-Json
Write-Host $configObj.GetType()

这个的输出:

System.Collections.Generic.Dictionary`2[System.String,System.Object]
System.Object[]

而且我无法像对象一样与 $configObj 交互并获取它的属性。事实上,我不知道如何从中获取任何信息。当我打印对象时,输出如下所示:

AC    Version        Location                                                                                                                                                                                           
---    -------        --------                                                                                                                                                                                           
True   v2.0.50727         C:\Windows\assembly\GAC_MSIL\System.Web.Extensions\3.5.0.0__31bf3856ad364e35\System.Web.Extensions.dll                                                                                             

Key   : DownloadURL
Value : https://example.com

Key   : dir
Value : 

当我期望它看起来像:

Key                                                                                                          Value                                                                                                       
---                                                                                                          -----                                                                                                       
DownloadURL                                                                                                  https://example.com          
dir 

有没有办法解决这个问题并从我的 ConvertFrom-Json 方法中获取与我的方法中存在的相同的对象?

提前致谢,

安迪

【问题讨论】:

  • [void][System.Reflection.Assembly]::LoadWithPartialName("System.Web.Extensions")Add-Type -AssemblyName System.Web.Extensions
  • 哇,太棒了。那解决了它!我什至没有想到 LoadWithPartialName 正在返回一个被 PowerShell 拾取的值。你是救生员!也很快!
  • @PetSerAl 出于好奇,你为什么用评论回答这个问题?

标签: json function powershell powershell-2.0


【解决方案1】:

每个语句的结果,除了赋值和递增/递减,都被视为函数返回的一部分。您不必使用 return 语句从函数返回某些内容。所以你的函数实际上返回两个对象:从LoadWithPartialName 方法加载的Assembly 对象和来自$obj 变量的字典。当您将多个函数结果分配给变量时,PowerShell 必须将结果打包到数组中。由于您实际上不需要Assembly 对象,您可以将LoadWithPartialName 方法的结果转换为[void]

[void][System.Reflection.Assembly]::LoadWithPartialName("System.Web.Extensions"‌​)

另外LoadWithPartialName 方法是Obsolete,你根本不应该使用它。对于加载程序集,您可以使用Add-Type 内置cmdlet:

Add-Type -AssemblyName System.Web.Extensions

由于您不在函数中使用命名块,所有代码都被视为end 块,因此您只处理函数中的最后一个管道输入。您应该使用process 块来处理每个管道输入对象:

process{
    $ser.DeserializeObject($json)
}

当语句返回集合时,PowerShell 会枚举此集合并将每个单独的集合的项目而不是集合写入单个元素。因此,如果您的 JSON 在顶层包含数组,您的函数将返回数组元素而不是数组本身,就像内置 ConvertFrom-Json 所做的那样。您可以使用一元数组运算符来防止返回数组的枚举:

,$ser.DeserializeObject($json)

总数:

function ConvertFrom-Json {
    param(
        [Parameter(ValueFromPipeline=$true)]
        [string]$json
    )
    begin {
        Add-Type -AssemblyName System.Web.Extensions
        $ser = New-Object System.Web.Script.Serialization.JavaScriptSerializer
    }
    process {
        ,$ser.DeserializeObject($json)
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-21
    • 1970-01-01
    • 1970-01-01
    • 2021-08-10
    • 1970-01-01
    • 2017-07-21
    • 2020-10-09
    • 1970-01-01
    相关资源
    最近更新 更多