json - 为什么此字符串不在 PowerShell 中序列化为简单的 JSON 字符串

标签 json powershell

见下文 $a$s是包含文本 "String" 的字符串但每个序列化与 ConvertTo-JSON 不同。
为什么不$s | ConvertToJson生产 "String" ??

PS W:\PowerShell\powowshell> $a="String"
PS W:\PowerShell\powowshell> $a
String
PS W:\PowerShell\powowshell> $a.gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object


PS W:\PowerShell\powowshell> $a | ConvertTo-Json
"String"


PS W:\PowerShell\powowshell> $s
String
PS W:\PowerShell\powowshell> $s.gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object


PS W:\PowerShell\powowshell> $s | ConvertTo-Json
{
    "value":  "String",
    "required":  "true"
}
背景故事$sparameterValue.ps1Get-Help 检查:
PS W:\PowerShell\powowshell> $cmd = (get-help -full W:\PowerShell\powowshell\examples\components\dosdir.ps1).Syntax.syntaxItem[0].parameter
PS W:\PowerShell\powowshell> $cmd | convertto-json
{
    "description":  [
                        {
                            "Text":  "The path to the directory to be listed"
                        }
                    ],
    "parameterValue":  {
                           "value":  "String",
                           "required":  "true"
                       },
...
$s = $cmd.parameterValue
dosdir.ps1 :
param(
    [String]$Path
)
CMD /C "DIR /B $Path"

最佳答案

PowerShell 的 ETS (Extended Type System)允许您使用其他属性(仅可由 PowerShell 代码直接访问)来修饰任何对象。
如果您使用 [string] 这样做实例(无论是你自己做还是其他命令为你做[1]),当对象被序列化ConvertTo-Json 时,这些额外的属性就会出现。 :

# Add a .foo property with value 'bar' to a string.
$decoratedString = 'hi' | Add-Member -PassThru foo bar

# Output the string as-is.
# The added property does NOT show.
$decoratedString

'---'

# Serialize the string to JSON.
# The added property DOES show and the string's actual content
# is presented as pseudo-property .value
$decoratedString | ConvertTo-Json
以上产生:
hi
---
{
  "value": "hi",
  "foo": "bar"
}
This GitHub issue讨论这种令人惊讶的行为。
解决方法 :
# .psobject.BaseObject returns the underlying, undecorated object.
PS> $decoratedString.psobject.BaseObject | ConvertTo-Json
hi

[1] 作为 js2010指出,数据检索 PowerShell 提供程序 cmdlet - Get-ChildItem , Get-Item , Get-Content , ... - 全部添加固定数量NoteProperty他们输出的对象的成员,即 PSPath , PSParentPath , PSChildName , PSDrive , PSProvider .
因此,如果您序列化使用 Get-Content 获得的字符串,您将遇到上面详述的相同问题。 :
PS> 'hi' > t.txt; Get-Content t.txt | ConvertTo-Json
{
  "value": "hi",
  "PSPath": "/Users/jdoe/t.txt",
  "PSParentPath": "/Users/jdoe",
  "PSChildName": "t.txt",
  "PSDrive": {
    "CurrentLocation": "Users/jdoe",
    "Name": "/",
    "Provider": {
      "ImplementingType": "Microsoft.PowerShell.Commands.FileSystemProvider",
      "HelpFile": "System.Management.Automation.dll-Help.xml",
      "Name": "FileSystem",
      "PSSnapIn": "Microsoft.PowerShell.Core",
...
请注意,在字符串的情况下,通过字符串连接或应用字符串运算符(例如 -replace)构建新字符串时,这些额外的属性将丢失。 :
# String concatenation
PS> 'hi' > t.txt; (Get-Content t.txt) + '!' | ConvertTo-Json
hi!

# Using -replace
PS> (Get-Content t.txt) -replace 'i', 'o' | ConvertTo-Json
ho
还要注意这个每个输出对象的装饰增加了相当多的内存和性能开销 ;为 Get-Content , GitHub issue #7537建议提供选择退出。

关于json - 为什么此字符串不在 PowerShell 中序列化为简单的 JSON 字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55854660/

相关文章:

ios - Swift 2 .plist dictArray 到远程 Json 数组错误

python - python 只获取元素数组中元素的一个值

javascript - 从 JSON 获取数据时不显示任何内容

java - Java中从url访问JSON对象

iis - 使用 Powershell 在 IIS 中设置网站的应用程序池

powershell - 修改 CSV 文件

c# - 错误 :Additional information: Unexpected character encountered while parsing value: W. 路径 '',第 2 行,位置 1

azure - 如何在Azure webjobs中加载外部模块Powershell

powershell - 为什么 powershell(ise) 有时会打印出我执行的代码?

azure - 在 Azure DevOps 管道中的 PowerShell 中使用参数