Convertire Newtonsoft.Json.Linq.JArray in un elenco di tipi di oggetti specifici


236

Ho la seguente variabile di tipo {Newtonsoft.Json.Linq.JArray}.

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

]}

Quello che voglio realizzare è convertire questo in List<SelectableEnumItem>cui SelectableEnumItemè il seguente tipo:

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

Sono piuttosto nuovo nella programmazione e non sono sicuro che ciò sia possibile. Qualsiasi aiuto con l'esempio funzionante sarà molto apprezzato.

Risposte:


480

Basta chiamare il array.ToObject<List<SelectableEnumItem>>()metodo. Restituirà ciò di cui hai bisogno.

Documentazione: convertire JSON in un tipo


4
Assicurati che la definizione della tua classe includa un costruttore senza parametri.
Faust,

1
Quindi, come gestire se l'array ha un campo null? Questa volta ricevo l'errore JsonSerializationException. Voglio i dati e voglio che rimangano nulli per qualsiasi dato nullo.
Ensar Turkoglu,

1
@nsarchar Hai verificato che la tua proprietà è nullable?
Jannik,

@realPro Ha appena lavorato per me. Sei sicuro di avere un array e che i JObject in quel JArray possono mappare correttamente?
VSO,

Vedrai anche questo errore Se usi accidentalmente il non generico JsonConvert.DeserializeObject(value)invece diJsonConvert.DeserializeObject<T>(value)
Chad Hedgcock il

42

L'esempio nella domanda è un caso più semplice in cui i nomi delle proprietà corrispondevano esattamente in json e nel codice. Se i nomi delle proprietà non corrispondono esattamente, ad es. La proprietà in json è "first_name": "Mark"e la proprietà nel codice viene FirstNamequindi utilizzata il metodo Select come segue

List<SelectableEnumItem> items = ((JArray)array).Select(x => new SelectableEnumItem
{
    FirstName = (string)x["first_name"],
    Selected = (bool)x["selected"]
}).ToList();

Signore, questo codice ottiene il primo valore dalla mia risposta, ma ho molti valori come posso ottenere tutti i valori, ma ho bisogno di ottenere un solo valore, intendo che c'è un nome e un cognome in risposta. Voglio ottenere solo il nome come posso Fai quello ?
tpbafk,

6

Il valore restituito dall'API nel mio caso, come mostrato qui:

{
  "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": "sebichondo@gmail.com",
      "id": 1,
      "addedDate": "2018-02-02T00:00:00",
      "modifiedDate": "2018-02-02T00:00:00"
    }
  ],
  "hasPreviousPage": false,
  "hasNextPage": false
}

La conversione dell'array di articoli in un elenco di client è stata gestita come mostrato qui:

 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);
        }

Grazie, ha funzionato per me usando oggetti dinamici in C #
Anthony McGrath,

2

Posso pensare a un metodo diverso per ottenere lo stesso

IList<SelectableEnumItem> result= array;

o (ho avuto una situazione in cui questo non funzionava bene)

var result = (List<SelectableEnumItem>) array;

o usa l'estensione linq

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

o

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

o più esplicitamente

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

si prega di prestare attenzione alla soluzione sopra che ho usato oggetto dinamico

Posso pensare ad alcune altre soluzioni che sono combinazioni di soluzioni di cui sopra. ma penso che copra quasi tutti i metodi disponibili là fuori.

Io stesso uso il primo


1
Non hai usato oggetti dinamici. Hai usato solo oggetti fortemente tipizzati. Per favore, guarda in CLR e DLR per le differenze tra i due.
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;
  }
}

È inoltre possibile utilizzare l'annotazione JsonProperty e deserializzare l'oggetto JSON in un elenco. 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

Utilizzare IList per ottenere il conteggio JArray e utilizzare Loop per convertire in elenco

       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());             
            }                         
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.