Konvertieren Sie Newtonsoft.Json.Linq.JArray in eine Liste bestimmter Objekttypen


236

Ich habe die folgende Variable vom Typ {Newtonsoft.Json.Linq.JArray}.

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

]}

Was ich erreichen will , ist dies zu konvertieren , List<SelectableEnumItem>wo SelectableEnumItemist die folgende Art:

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

Ich bin ziemlich neu in der Programmierung und ich bin mir nicht sicher, ob dies möglich ist. Jede Hilfe mit Arbeitsbeispiel wird sehr geschätzt.

Antworten:


479

Rufen Sie einfach die array.ToObject<List<SelectableEnumItem>>()Methode auf. Es wird zurückgeben, was Sie brauchen.

Dokumentation: Konvertieren Sie JSON in einen Typ


4
Stellen Sie sicher, dass Ihre Klassendefinition einen parameterlosen Konstruktor enthält.
Faust

1
Wie gehe ich also vor, wenn das Array ein Nullfeld hat? Diesmal erhalte ich den Fehler JsonSerializationException. Ich möchte die Daten und ich möchte, dass sie für alle Nulldaten null bleiben.
Ensar Turkoglu

1
@nsarchar Haben Sie überprüft, ob Ihre Eigenschaft nullbar ist?
Jannik

@realPro Hat gerade für mich gearbeitet. Sind Sie sicher, dass Sie ein Array haben und dass die JObjects in diesem JArray ordnungsgemäß zugeordnet werden können?
VSO

Sie werden auch diesen Fehler sehen, wenn Sie versehentlich das nicht-generische JsonConvert.DeserializeObject(value)anstelle vonJsonConvert.DeserializeObject<T>(value)
Chad Hedgcock

42

Das Beispiel in der Frage ist ein einfacher Fall, in dem die Eigenschaftsnamen in json und im Code genau übereinstimmen. Wenn die Eigenschaftsnamen nicht genau übereinstimmen, z. B. die Eigenschaft in json "first_name": "Mark"und die Eigenschaft im Code, FirstNameverwenden Sie die Select-Methode wie folgt

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

Sir, dieser Code erhält den ersten Wert aus meiner Antwort, aber ich habe viele Werte, wie ich alle Werte erhalten kann. Aber ich muss nur einen Wert erhalten. Ich meine, es gibt einen Vor- und Nachnamen in der Antwort. Ich möchte nur den Vornamen erhalten, wie kann ich TU das ?
tpbafk

6

Der API-Rückgabewert in meinem Fall wie hier gezeigt:

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

Die Konvertierung des Elementarrays in eine Liste von Clients wurde wie folgt durchgeführt:

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

Vielen Dank, dass dies für mich mit dynamischen Objekten in C # funktioniert hat
Anthony McGrath

2

Ich kann mir verschiedene Methoden vorstellen, um dasselbe zu erreichen

IList<SelectableEnumItem> result= array;

oder (ich hatte eine Situation, in der diese nicht gut funktionierte)

var result = (List<SelectableEnumItem>) array;

oder verwenden Sie die Linq-Erweiterung

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

oder

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

oder expliziter

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

Bitte beachten Sie in der obigen Lösung, dass ich dynamisches Objekt verwendet habe

Ich kann mir einige weitere Lösungen vorstellen, die Kombinationen der oben genannten Lösungen sind. aber ich denke, es deckt fast alle verfügbaren Methoden ab.

Ich selbst benutze den ersten


1
Sie haben keine dynamischen Objekte verwendet. Sie haben nur stark typisierte Objekte verwendet. Bitte schauen Sie in CLR und DLR nach den Unterschieden zwischen den beiden.
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;
  }
}

Sie können auch die JsonProperty-Annotation verwenden und Ihr JSON-Objekt in eine Liste deserialisieren. 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

Verwenden Sie IList, um die JArray-Anzahl abzurufen, und verwenden Sie Loop, um sie in eine Liste zu konvertieren

       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());             
            }                         
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.