skip to Main Content

I am working to built a function to construct a json payload for an API call. The json payload will have a main "member", but I need to add a sub-member which is really a json array. I have this almost working, but I have been unable to get it completely working.

Here are two examples (which produce different -but incorrect- results):

This example produces the correct structure (except for the required opening and closing {} around the array:

[PSCustomObject] $contactMain = @{}
[PSCustomObject] $contactDetail_Native = @{}
[array] $contactDetail_Custom = @()

$contactDetail_Custom = `
    [PSCustomObject]@{
        field = '1'
        value = '1001'
    }

$contactDetail_Custom += $contactDetail_Custom

$contactDetail_Custom = `
    [PSCustomObject]@{
        field = '2'
        value = '1002'
    }

$contactDetail_Custom += $contactDetail_Custom

$contactDetail_Native = `
    [ordered]@{
        email     = '[email protected]'
        lastName  = 'Banner'
        firstName = 'Bruce'
    }

$contactDetail_Native.Add('fieldValues', $contactDetail_Custom)

$contactMain | Add-Member -MemberType NoteProperty -Name 'contact' -Value $contactDetail_Native -Force
#$contactMain | Add-Member -MemberType NoteProperty -Name 'fieldValues' -Value $contactDetail_Custom -Force

$contactMain = $contactMain | ConvertTo-Json
$contactMain

This example renders the values, but fieldValues needs to be inside the contacts member:

[PSCustomObject] $contactMain = @{}
[PSCustomObject] $contactDetail_Native = @{}
[array] $contactDetail_Custom = @()

$contactDetail_Custom = `
    [PSCustomObject]@{
        field = '1'
        value = '1001'
    }

$contactDetail_Custom += $contactDetail_Custom

$contactDetail_Custom = `
    [PSCustomObject]@{
        field = '2'
        value = '1002'
    }

$contactDetail_Custom += $contactDetail_Custom

$contactDetail_Native = `
    [ordered]@{
        email     = '[email protected]'
        lastName  = 'Banner'
        firstName = 'Bruce'
    }

#$contactDetail_Native.Add('fieldValues', $contactDetail_Custom)

$contactMain | Add-Member -MemberType NoteProperty -Name 'contact' -Value $contactDetail_Native -Force
$contactMain | Add-Member -MemberType NoteProperty -Name 'fieldValues' -Value $contactDetail_Custom -Force

$contactMain = $contactMain | ConvertTo-Json
$contactMain

The way I need it to render is like this:

{"contact": {
    "firstName":  "Bruce",
    "lastName":  "Banner",
    "email":  "[email protected]",
    "fieldValues":  [
                        {
                            "field":  "1",
                            "value":  "1001"
                        },
                        {
                            "field":  "2",
                            "value":  "1002"
                        }
                    ]
}}

What am I doing wrong?

Thanks!

2

Answers


  1. Chosen as BEST ANSWER

    Looks like I was able to figure this out on my own. The solution was to set the Depth parameter on the ConvertTo-Json cmdlet using the first code example I provided.

    Here is the final version that produces the result I need:

    [PSCustomObject] $contactMain          = @{}
    [PSCustomObject] $contactDetail_Native = @{}
    [array]          $contactDetail_Custom = @{}
    [array]          $contactDetail        = @()
    
    
    $contactDetail_Custom = `
        [PSCustomObject]@{
            field = '1'
            value = '1001'
        }
    
    $contactDetail += $contactDetail_Custom
    
    $contactDetail_Custom = `
        [PSCustomObject]@{
            field = '2'
            value = '1002'
        }
    
    $contactDetail += $contactDetail_Custom
    
    $contactDetail_Native = `
        [ordered]@{
            email     = '[email protected]'
            lastName  = 'Banner'
            firstName = 'Bruce'
        }
    
    $contactDetail_Native.Add('fieldValues', $contactDetail)
    
    $contactMain | Add-Member -MemberType NoteProperty -Name 'contact' -Value $contactDetail_Native -Force
    
    $contactMain = $contactMain | ConvertTo-Json -Depth 100
    $contactMain
    

  2. You might want to use this ConvertTo-Expression to build a template and/or get an impression of the PowerShell structure:

    Install-Script -Name ConvertTo-Expression
    $YourJson |ConvertFrom-Json |ConvertTo-Expression
    
    [pscustomobject]@{contact = [pscustomobject]@{
            firstName = 'Bruce'
            lastName = 'Banner'
            email = '[email protected]'
            fieldValues =
                [pscustomobject]@{
                    field = '1'
                    value = '1001'
                },
                [pscustomobject]@{
                    field = '2'
                    value = '1002'
                }
        }}
    

    To automatically build the fieldValues, you could do something like this:

    function Get-CustomDetail {
        param([Parameter(ValueFromPipeline=$true)][String]$Field)
        process {
            [pscustomobject]@{
                field = $Field
                value = "100$Field"
            }
        }
    }
    
    [pscustomobject]@{contact = [pscustomobject]@{
            firstName = 'Bruce'
            lastName = 'Banner'
            email = '[email protected]'
            fieldValues = @(1,2 |Get-CustomDetail) # @(...) forces an array for single items
        }
    } |ConvertTo-Json -Depth 9
    
    {
      "contact": {
        "firstName": "Bruce",
        "lastName": "Banner",
        "email": "[email protected]",
        "fieldValues": [
          {
            "field": "1",
            "value": "1001"
          },
          {
            "field": "2",
            "value": "1002"
          }
        ]
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search