Always count property as array (JSON convert failure)

Hi,

I have a problem converting some data to JSON because some objects have array properties while other only have a single property.

Let me try illustrate the problem:

# Object with object-array property inside
$customProp = @()
$customProp += New-Object psobject -Property @{ Name="Test1"; Size="100"}
$customProp += New-Object psobject -Property @{ Name="Test2"; Size="100"}

$object1 = New-Object psobject -Property @{ Name="Object1"; Something="Weird"}
$final1 = $object1 | Select-Object Name, Something, @{n="Custom";e={$customProp}}


# Object with object property inside
$customProp = @()
$customProp += New-Object psobject -Property @{ Name="Test10"; Size="200"}


$object2 = New-Object psobject -Property @{ Name="Object2"; Something="Strange"}
$final2 = $object2 | Select-Object Name, Something, @{n="Custom";e={$customProp}}


$list = @()
$list += $final1
$list += $final2
$list

The output of the above should be:

Name    Something Custom                                            
----    --------- ------                                            
Object1 Weird     {@{Name=Test1; Size=100}, @{Name=Test2; Size=100}}
Object2 Strange   @{Name=Test10; Size=200}                          

And the problem is showing already here. Object1’s Custom property has and extra set of {} around its content while Object2 is lacking those.
Resulting converting it to JSON:

$list | ConvertTo-Json -Depth 3

[
    {
        "Name":  "Object1",
        "Something":  "Weird",
        "Custom":  {
                       "value":  [
                                     {
                                         "Name":  "Test1",
                                         "Size":  "100"
                                     },
                                     {
                                         "Name":  "Test2",
                                         "Size":  "100"
                                     }
                                 ],
                       "Count":  2
                   }
    },
    {
        "Name":  "Object2",
        "Something":  "Strange",
        "Custom":  {
                       "Name":  "Test10",
                       "Size":  "200"
                   }
    }
]

I really need to have it to be same like this:

[
    {
        "Name":  "Object1",
        "Something":  "Weird",
        "Custom":  [
                                     {
                                         "Name":  "Test1",
                                         "Size":  "100"
                                     },
                                     {
                                         "Name":  "Test2",
                                         "Size":  "100"
                                     }
                                 ]

                   
    },
    {
        "Name":  "Object2",
        "Something":  "Strange",
        "Custom":  [
			{
                       		"Name":  "Test10",
                       		"Size":  "200"
                   	}
		]
    }
]

I need to generate a C# Class from it like this:

public class Custom
{
    public string Name { get; set; }
    public string Size { get; set; }
}

public class RootObject
{
    public string Name { get; set; }
    public string Something { get; set; }
    public List Custom { get; set; }
}

Right now json2charp.com gives me classes like this, which I do not fancy :slight_smile:

public class Value
{
    public string Name { get; set; }
    public string Size { get; set; }
}

public class Custom
{
    public List value { get; set; }
    public int Count { get; set; }
    public string Name { get; set; }
    public string Size { get; set; }
}

public class RootObject
{
    public string Name { get; set; }
    public string Something { get; set; }
    public Custom Custom { get; set; }
}

Any help?

I have temporarily overcome this by initializing the $CustomProp array wtih $null ($CustomProp = @($null)) and then do what is necessary with regex afterwards:

-replace ‘“Custom”:{“value”:[null,’, ‘“Custom”:[’ -replace ‘],“Count”:\d},’, ‘],’

If anyone could tell how to do it properly I would still be very glad :slight_smile:

There’s a lot going on in the code where you’re initializing your objects. When I changed it to this the JSON output matched what you’re looking for:

$list = @(
    [pscustomobject] @{
        Name = 'Object1'
        Something = 'Weird'
        Custom = @(
            [pscustomobject] @{
                Name = 'Test1'
                Size = '100'
            }

            [pscustomobject] @{
                Name = 'Test2'
                Size = '100'
            }
        )
    }

    [pscustomobject] @{
        Name = 'Object2'
        Something = 'Strange'
        Custom = @(
            [pscustomobject] @{
                Name = 'Test10'
                Size = '200'
            }
        )
    }
)

$list | ConvertTo-Json -Depth 3

Figuring out they ‘why’ of your original output is a little trickier. You used the @() operator to force your $customProp variables to be arrays, but then you put those variables into an Expression script block of Select-Object, which will unroll the single-element array. (Which is why you see it as a single object when looking at both $list and the JSON conversion in the original output.)

As for that Value and Count bit in your original output? I have no idea where those are coming from. Could be that you’ve found some bug in the JSON converter, but I’m not seeing it at the moment.

Well I’m not sure why exactly you’re doing the Select-Object thing, but if you initialize the objects using the custom property, then it works.

$customProp = @()
$customProp += New-Object psobject -Property @{ Name="Test1"; Size="100"}
$customProp += New-Object psobject -Property @{ Name="Test2"; Size="100"}
$object1 = New-Object psobject -Property @{ Name="Object1"; Something="Weird"; Custom = $customProp }
 
# Object with object property inside
$customProp = @()
$customProp += New-Object psobject -Property @{ Name="Test10"; Size="200"}
$object2 = New-Object psobject -Property @{ Name="Object2"; Something="Strange"; Custom = $customProp }

PS C:\Users\mni> $object1

Custom                                                                                Name                                                                                  Something                                                                            
------                                                                                ----                                                                                  ---------                                                                            
{@{Name=Test1; Size=100}, @{Name=Test2; Size=100}}                                    Object1                                                                               Weird                                                                                


PS C:\Users\mni> $object2

Custom                                                                                Name                                                                                  Something                                                                            
------                                                                                ----                                                                                  ---------                                                                            
{@{Name=Test10; Size=200}}                                                            Object2                                                                               Strange                                                                              

Edit: And then Dave just ninja-solved the riddle.