Десериализовать PSObject из JSON в список на C#

У меня есть приложение на C# для отображения информации из Active Directory с помощью PowerShell.

class userps
{
    public string Name { get; set; }
    public bool Enabled { get; set; }
}

PSObject[] results = pipeline.Invoke().ToArray();
List<userps> listUserps = new List<userps>();
foreach (PSObject obj in results)
{
     lista = JsonConvert.DeserializeObject<List<userps>>(obj.ToString());
}

Если объект возвращает данные как минимум двух элементов, например:

[
  {
    "Name":"xxx",
    "Enabled":true
  },
  {
    "Name":"yyy",
    "Enabled":true
  }
]

Тогда все в порядке, List.Count = 2. Если, однако, он возвращает один элемент:

[
  {
    "Name":"xxx",
    "Enabled":true
  }
]

Тогда List.Count = 0 и возникает исключение:

Newtonsoft.Json.JsonSerializationException: «Невозможно десериализовать текущий объект JSON (например, {"name":"value"}) в тип «System.Collections.Generic.List`1[ConsoleApp1.userps]», поскольку для этого типа требуется массив JSON (например, [1,2,3]) для правильной десериализации.
Чтобы исправить эту ошибку, либо измените JSON на массив JSON (например, [1,2,3]), либо измените десериализованный тип, чтобы он был обычным типом .NET (например, не примитивным типом, таким как целое число, не тип коллекции, такой как массив или список), который можно десериализовать из объекта JSON.
JsonObjectAttribute также можно добавить к типу, чтобы заставить его десериализоваться из объекта JSON.
Путь «Имя», строка 2, позиция 11».

Как мне решить эту проблему, чтобы она работала для одного элемента, а также для нескольких?


person MatDob    schedule 11.06.2018    source источник
comment
Осмотрите obj.ToString().   -  person CodeCaster    schedule 11.06.2018
comment
Возможный дубликат JsonConvert.DeserializeObject‹IEnumerable‹Book››   -  person SᴇM    schedule 11.06.2018
comment
@SeM ваши дублированные ссылки не имеют отношения к этому делу. OP уже знает и успешно справляется с дезарейлизацией массива. Он терпит неудачу только тогда, когда массив содержит один элемент   -  person CodeNotFound    schedule 11.06.2018
comment
@CodeNotFound Я просто хочу показать OP, что если у него есть правильная строка json и она правильно десериализована, это вряд ли произойдет, потому что не имеет значения, 1 элемент или 2.   -  person SᴇM    schedule 11.06.2018


Ответы (1)


Похоже, что объект, который вы получаете от своей команды PowerShell, не является коллекцией и сериализуется как объект в JSON. Это обычное поведение PowerShell, когда команда возвращает только один объект вместо списка.

Пример:

Get-Service | ConvertTo-Json

[
    {
        "Name":  "AdobeFlashPlayerUpdateSvc",
        ...
    },  
    {
        "Name":  "ALG",
        ...
    },
    ...
]

Get-Service -Name 'NetLogon' | ConvertTo-Json

{
    "Name":  "NetLogon",
    ...
}

Чтобы избежать этого, инкапсулируйте свою команду в конструкторе массива и замените канал параметром InputObject:

ConvertTo-Json -InputObject @(Get-Service -Name 'NetLogon')

[
    {
        "Name":  "NetLogon",
        ...
    }
]
person Julien Nury    schedule 11.06.2018