Converta Newtonsoft.Json.Linq.JArray em uma lista de tipos de objetos específicos

236

Eu tenho a seguinte variável do tipo {Newtonsoft.Json.Linq.JArray}.

properties["Value"] {[
  {
    "Name": "Username",
    "Selected": true
  },
  {
    "Name": "Password",
    "Selected": true
  }

]}

O que eu quero realizar é converter isso para List<SelectableEnumItem>onde SelectableEnumItemé o seguinte tipo:

public class SelectableEnumItem
    {
        public string Name { get; set; }
        public bool Selected { get; set; }
    }

Eu sou bastante novo em programação e não tenho certeza se isso é possível. Qualquer ajuda com o exemplo de trabalho será muito apreciada.

Mdb
fonte

Respostas:

480

Basta chamar o array.ToObject<List<SelectableEnumItem>>()método Ele retornará o que você precisa.

Documentation: Converter JSON em um tipo

HoberMellow
fonte
4
Certifique-se de que sua definição de classe inclua um construtor sem parâmetros.
Faust
1
Então, como lidar se a matriz tiver um campo nulo? Desta vez, recebo o erro JsonSerializationException. Quero os dados e quero que permaneçam nulos para quaisquer dados nulos.
precisa saber é o seguinte
1
@nsarchar Você verificou se sua propriedade é anulável?
Jannik
@realPro Apenas funcionou para mim. Você tem certeza de que possui uma matriz e que os JObjects nesse JArray podem mapear corretamente?
VSO
Você também verá este erro Se você acidentalmente usar o não-genérico em JsonConvert.DeserializeObject(value)vez deJsonConvert.DeserializeObject<T>(value)
Chad Hedgcock
42

O exemplo da pergunta é um caso mais simples, em que os nomes das propriedades correspondiam exatamente ao json e ao código. Se os nomes das propriedades não corresponderem exatamente, por exemplo, a propriedade em json is "first_name": "Mark"e a propriedade no código FirstName, use o método Select da seguinte maneira

List<SelectableEnumItem> items = ((JArray)array).Select(x => new SelectableEnumItem
{
    FirstName = (string)x["first_name"],
    Selected = (bool)x["selected"]
}).ToList();
Souvik Basu
fonte
Se a resposta ajudou de alguma forma, por favor, marque como resposta, caso a sua dúvida não tenha sido solucionada, por favor, poste novamente. faça isso ?
tpbafk
6

O valor de retorno da API no meu caso, como mostrado aqui:

{
  "pageIndex": 1,
  "pageSize": 10,
  "totalCount": 1,
  "totalPageCount": 1,
  "items": [
    {
      "firstName": "Stephen",
      "otherNames": "Ebichondo",
      "phoneNumber": "+254721250736",
      "gender": 0,
      "clientStatus": 0,
      "dateOfBirth": "1979-08-16T00:00:00",
      "nationalID": "21734397",
      "emailAddress": "[email protected]",
      "id": 1,
      "addedDate": "2018-02-02T00:00:00",
      "modifiedDate": "2018-02-02T00:00:00"
    }
  ],
  "hasPreviousPage": false,
  "hasNextPage": false
}

A conversão da matriz de itens em lista de clientes foi tratada como mostrado aqui:

 if (responseMessage.IsSuccessStatusCode)
        {
            var responseData = responseMessage.Content.ReadAsStringAsync().Result;
            JObject result = JObject.Parse(responseData);

            var clientarray = result["items"].Value<JArray>();
            List<Client> clients = clientarray.ToObject<List<Client>>();
            return View(clients);
        }
stephen ebichondo
fonte
Graças isso funcionou para mim usando objetos dinâmicos em C #
Anthony McGrath
2

Eu posso pensar em um método diferente para alcançar o mesmo

IList<SelectableEnumItem> result= array;

ou (tive alguma situação em que este não funcionou bem)

var result = (List<SelectableEnumItem>) array;

ou use extensão linq

var result = array.CastTo<List<SelectableEnumItem>>();

ou

var result= array.Select(x=> x).ToArray<SelectableEnumItem>();

ou mais explicitamente

var result= array.Select(x=> new SelectableEnumItem{FirstName= x.Name, Selected = bool.Parse(x.selected) });

por favor, preste atenção na solução acima eu usei objeto dinâmico

Posso pensar em mais algumas soluções que são combinações das soluções acima. mas acho que abrange quase todos os métodos disponíveis no mercado.

Eu uso o primeiro

Mo Hrad A
fonte
1
Você não usou nenhum objeto dinâmico. Você usou apenas o objeto fortemente digitado. Por favor, procure em CLR e DLR as diferenças entre os dois.
user1789573
2
using Newtonsoft.Json.Linq;
using System.Linq;
using System.IO;
using System.Collections.Generic;

public List<string> GetJsonValues(string filePath, string propertyName)
{
  List<string> values = new List<string>();
  string read = string.Empty;
  using (StreamReader r = new StreamReader(filePath))
  {
    var json = r.ReadToEnd();
    var jObj = JObject.Parse(json);
    foreach (var j in jObj.Properties())
    {
      if (j.Name.Equals(propertyName))
      {
        var value = jObj[j.Name] as JArray;
        return values = value.ToObject<List<string>>();
      }
    }
    return values;
  }
}
Mohammed Hossen
fonte
Você também pode usar a anotação JsonProperty e desserializar seu objeto JSON para uma lista. public class SelectableEnumItem { [JsonProperty("Name")] public string Name { get; set; } [JsonProperty("Selected")] public bool Selected { get; set; } } public IList<SelectableEnumItem> GetListOfObject(string jsonTextHere) { return JsonConvert.DeserializeObject<List<SelectableEnumItem>>(jsonTextHere); }
Mohammed Hossen
1

Use IList para obter o JArray Count e use Loop para converter em lista

       var array = result["items"].Value<JArray>();

        IList collection = (IList)array;

        var list = new List<string>();

        for (int i = 0; i < collection.Count; j++)
            {
              list.Add(collection[i].ToString());             
            }                         
Kumaran
fonte