Skip to content

ConvertFrom-Json doesn't unwrap arrays on output, resulting in an extraneous wrapper JSON object with Count and Value properties on reconversion #3153

Closed

Description

Steps to reproduce

'[ 1, 2 ]' | ConvertFrom-Json | ConvertTo-Json

Expected behavior

[
    1,
    2
]

Actual behavior

{
    "value":  [
                  1,
                  2
              ],
    "Count":  2
}

I believe the root cause is that ConvertFrom-Json sends arrays as a whole through the pipeline instead of unwrapping them.

Analysis, more examples, and workaround here: http://stackoverflow.com/a/38212718/45375

Environment data

PowerShell v6.0.0-alpha (v6.0.0-alpha.15) on Darwin Kernel Version 16.4.0: Thu Dec 22 22:53:21 PST 2016; root:xnu-3789.41.3~3/RELEASE_X86_64
PowerShell v5.1.14393.693 on Microsoft Windows 10 Pro (64-bit; v10.0.14393)

Activity

  1. added this to the milestone on Feb 21, 2017
  2. PetSerAl commented on Feb 26, 2017

    @PetSerAl
    Contributor

    Workaround: Remove-TypeData -TypeName System.Array.

  3. SteveL-MSFT commented on Mar 16, 2017

    @SteveL-MSFT
    Member

    Fixed in alpha.17 via #3231

  4. mklement0 commented on Mar 16, 2017

    @mklement0
    ContributorAuthor

    Steve Lee (@SteveL-MSFT): The example in this bug report now works as intended in alpha.17, but ConvertFrom-Json still unexpectedly sends an output array as a whole through the pipeline:

    > '[ 1, 2 ]' | ConvertFrom-Json | % GetType | % Name
    Object[]

    Contrast this with a regular array:

    > 1, 2 | % GetType | % Name
    Int32
    Int32
  5. SteveL-MSFT commented on Mar 16, 2017

    @SteveL-MSFT
    Member

    Michael Klement (@mklement0) can you open a new issue? thanks!

  6. PetSerAl commented on Mar 16, 2017

    @PetSerAl
    Contributor

    Michael Klement (@mklement0)
    Should

    '[ 1 ]' | ConvertFrom-Json | ConvertTo-Json

    return [ 1 ]?

  7. mklement0 commented on Mar 16, 2017

    @mklement0
    ContributorAuthor

    PetSerAl: It's a fair point - if you unwrap the array, information is lost.

    But that equally applies to:

    , 1 | ForEach-Object { $_ }  # or even:  , 1 | ForEach-Object { , $_ }

    So it's weighing PowerShell's normal collection handling against preserving information about the input.

    Perhaps if no one ever notices in practice that the collection is passed as a whole, the alpha.17 behavior is fine.

    Not sure what the right answer is.

    Steve Lee (@SteveL-MSFT): Thanks; I will, once I have clarity over whether that's indeed a problem.

  8. JohnLBevan commented on Feb 15, 2018

    @JohnLBevan
    Contributor

    NB: Noticed this in practice... passing the output of ConvertFrom-Json down the pipeline to a function with arguments ValueFromPipelineByPropertyName gives error The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input.

    PetSerAl's comment is valid though; so perhaps a switch is required -UnwrapCollection to select preferred behaviour at runtime?

  9. mklement0 commented on Feb 17, 2018

    @mklement0
    ContributorAuthor

    John Bevan (@JohnLBevan): Let's continue the conversation at #3424, which is still open (and where you've previously commented too ).

    In short, my suggestion is to make ConvertFrom-Json's behavior PowerShell-friendly by default (by unwrapping, as usual), while giving users the ability to opt into array-as-single-output-object behavior with -NoEnumerate, if needed.

    Thus, the above example would become:

    '[ 1 ]' | ConvertFrom-Json -NoEnumerate | ConvertTo-Json
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions