Как загрузить файл JSON и преобразовать его в объект определенного типа?

У меня есть тип FooObject, и у меня есть файл JSON, который был сериализован из экземпляра FooObject. Теперь я хочу использовать ConvertFrom-Json для загрузки JSON файла в память и скрывать вывод команды до объекта FooObject, а затем использовать новый объект в командлете Set-Bar, который принимает только FooObject в качестве параметра тип.

Но я заметил, что тип вывода ConvertFrom-Json равен PSCustomObject, и я не нашел способа конвертировать PSCustomObject в FooObject.

Ответ 1

Попробуйте добавить пользовательский объект к FooObject:

$foo = [FooObject](Get-Content 'C:\path\to\your.json' | Out-String | ConvertFrom-Json)

Если это не сработает, попробуйте создать экземпляр FooObject со свойствами входного объекта (если класс имеет такой конструктор):

$json = Get-Content 'C:\path\to\your.json' | Out-String | ConvertFrom-Json
$foo = New-Object FooObject ($json.Foo, $json.Bar, $json.Baz)

Если это также не сработает, вам нужно создать пустой экземпляр FooObject и затем обновить его свойства:

$json = Get-Content 'C:\path\to\your.json' | Out-String | ConvertFrom-Json
$foo = New-Object FooObject
$foo.AA = $json.Foo
$foo.BB = $json.Bar
$foo.CC = $json.Baz

Ответ 3

Я понимаю, что это старый пост, но я нашел более эффективный способ сделать это, если приведение не работает. Обязательно попробуйте сыграть первым. Приведение будет работать до тех пор, пока ваш класс не содержит вложенных коллекций пользовательских типов. Скажем, ваш класс выглядит следующим образом.

class Container 
{
    [string] $Id
    [string] $Name
    [System.Collections.Generic.List[Process]] $Processes
}
class Process
{
    [string] $Id
    [string] $Name
}

ConvertFrom-Json преобразует его в [PSCustomObject], но превращает List [Process] в Object [], что приведет к тому, что любая операция приведения вызовет следующее исключение.

Невозможно преобразовать значение "System.Object []" типа "System.Object []" в тип "System.Collections.Generic.List'1 [Process]".

ConvertToFinalInvalidCastException

Используйте следующее для десериализации этого типа иерархии.

$serializer = [System.Web.Script.Serialization.JavaScriptSerializer]::new()

$content = $serializer.Deserialize((Get-Content -Path $JsonFilePath), [YourCustomType])

[System.Web.Script.Serialization.JavaScriptSerializer] - это то, как ConvertFrom-Json работает в фоновом режиме. Итак, я только что создал новый экземпляр этого и смог преобразовать многоуровневый файл (четыре уровня, если быть точным, и каждый уровень имел набор уровней ниже него) легко в мой класс powershell. Я также понимаю, что это можно упростить до следующего, но это легче читать выше.

$content = [System.Web.Script.Serialization.JavaScriptSerializer]::new().Deserialize((Get-Content -Path $JsonFilePath), [YourCustomType])