Convertir Newtonsoft.Json.Linq.JArray en une liste de types d'objets spécifiques

236

J'ai la variable de type suivante {Newtonsoft.Json.Linq.JArray}.

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

]}

Ce que je veux accomplir est de convertir ceci en List<SelectableEnumItem>SelectableEnumItemest le type suivant:

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

Je suis plutôt novice en programmation et je ne sais pas si c'est possible. Toute aide avec l'exemple de travail sera grandement appréciée.

Mdb
la source

Réponses:

480

Appelez simplement la array.ToObject<List<SelectableEnumItem>>()méthode. Il vous rendra ce dont vous avez besoin.

Documentation: convertir JSON en un type

HoberMellow
la source
4
Assurez-vous que votre définition de classe inclut un constructeur sans paramètre.
Faust
1
Alors, comment gérer si le tableau a un champ nul? Cette fois, je reçois l'erreur JsonSerializationException. Je veux les données et je veux qu'elles restent nulles pour toutes les données nulles.
Ensar Turkoglu
1
@nsarchar Avez-vous vérifié que votre propriété est nullable?
Jannik
@realPro Je viens de travailler pour moi. Etes-vous sûr que vous disposez d'un tableau et que les JObjects dans ce JArray peuvent mapper correctement?
VSO
Vous verrez également cette erreur Si vous utilisez accidentellement le non générique JsonConvert.DeserializeObject(value)au lieu deJsonConvert.DeserializeObject<T>(value)
Chad Hedgcock
42

L'exemple de la question est un cas plus simple où les noms de propriété correspondent exactement dans json et dans le code. Si les noms de propriété ne correspondent pas exactement, par exemple la propriété dans json est "first_name": "Mark"et la propriété dans le code est FirstNamealors utilisez la méthode Select comme suit

List<SelectableEnumItem> items = ((JArray)array).Select(x => new SelectableEnumItem
{
    FirstName = (string)x["first_name"],
    Selected = (bool)x["selected"]
}).ToList();
Souvik Basu
la source
Monsieur, ce code obtient la première valeur de ma réponse, mais j'ai beaucoup de valeurs, comment puis-je obtenir toutes les valeurs.Mais je dois obtenir une seule valeur, je veux dire qu'il y a un prénom et un nom en réponse.Je veux obtenir juste le prénom comment puis-je faire ça?
tpbafk
6

La valeur de retour de l'API dans mon cas, comme indiqué ici:

{
  "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
}

La conversion du tableau d'éléments en liste de clients a été gérée comme indiqué ici:

 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
la source
Merci, cela a fonctionné pour moi en utilisant des objets dynamiques en C #
Anthony McGrath
2

Je peux penser à différentes méthodes pour atteindre le même

IList<SelectableEnumItem> result= array;

ou (j'ai eu une situation où celle-ci ne fonctionnait pas bien)

var result = (List<SelectableEnumItem>) array;

ou utilisez l'extension linq

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

ou

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

ou plus explicitement

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

veuillez faire attention dans la solution ci-dessus J'ai utilisé un objet dynamique

Je peux penser à d'autres solutions qui sont des combinaisons des solutions ci-dessus. mais je pense que cela couvre presque toutes les méthodes disponibles.

Moi j'utilise le premier

Mo Hrad A
la source
1
Vous n'avez utilisé aucun objet dynamique. Vous avez uniquement utilisé un objet fortement typé. S'il vous plaît, regardez dans CLR et DLR pour les différences entre les deux.
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
la source
Vous pouvez également utiliser l'annotation JsonProperty et désérialiser votre objet JSON dans une liste. 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

Utilisez IList pour obtenir le nombre JArray et utilisez la boucle pour convertir en liste

       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
la source