Convierta Newtonsoft.Json.Linq.JArray a una lista de tipos de objetos específicos

236

Tengo la siguiente variable de tipo {Newtonsoft.Json.Linq.JArray}.

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

]}

Lo que quiero lograr es convertir esto a List<SelectableEnumItem>donde SelectableEnumItemestá el siguiente tipo:

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

Soy bastante nuevo en programación y no estoy seguro de si esto es posible. Cualquier ayuda con el ejemplo de trabajo será muy apreciada.

Mdb
fuente

Respuestas:

480

Solo llame al array.ToObject<List<SelectableEnumItem>>()método. Le devolverá lo que necesita.

Documentación: Convertir JSON a un tipo

HoberMellow
fuente
44
Asegúrese de que su definición de clase incluya un constructor sin parámetros.
Fausto
1
Entonces, ¿cómo manejar si la matriz tiene un campo nulo? Esta vez me sale el error JsonSerializationException. Quiero los datos y quiero que permanezcan nulos para cualquier dato nulo.
Ensar Turkoglu
1
@nsarchar ¿Ha verificado que su propiedad es anulable?
Jannik
@realPro simplemente funcionó para mí. ¿Está seguro de que tiene una matriz y de que los JObjects en ese JArray pueden mapearse correctamente?
VSO
También verá este error si utiliza accidentalmente el no genérico en JsonConvert.DeserializeObject(value)lugar deJsonConvert.DeserializeObject<T>(value)
Chad Hedgcock
42

El ejemplo en la pregunta es un caso más simple en el que los nombres de las propiedades coinciden exactamente en json y en el código. Si los nombres de las propiedades no coinciden exactamente, por ejemplo, la propiedad en json es "first_name": "Mark"y la propiedad en el código es FirstNameusar el método Select de la siguiente manera

List<SelectableEnumItem> items = ((JArray)array).Select(x => new SelectableEnumItem
{
    FirstName = (string)x["first_name"],
    Selected = (bool)x["selected"]
}).ToList();
Souvik Basu
fuente
Sir este código obteniendo el primer valor de mi respuesta, pero tengo muchos valores, ¿cómo puedo obtener todos los valores? Pero necesito obtener solo un valor, quiero decir que hay un nombre y un apellido en respuesta. Haz eso ?
tpbafk
6

El valor de retorno de API en mi caso como se muestra aquí:

{
  "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 conversión de la matriz de elementos a la lista de clientes se manejó como se muestra aquí:

 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
fuente
Gracias, esto funcionó para mí usando objetos dinámicos en C #
Anthony McGrath
2

Puedo pensar en un método diferente para lograr lo mismo

IList<SelectableEnumItem> result= array;

o (tuve una situación en la que este no funcionó bien)

var result = (List<SelectableEnumItem>) array;

o use la extensión linq

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

o

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

o más explícitamente

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

Por favor, preste atención en la solución anterior. Utilicé el objeto dinámico

Puedo pensar en algunas soluciones más que son combinaciones de las soluciones anteriores. pero creo que cubre casi todos los métodos disponibles por ahí.

Yo uso el primero

Mo Hrad A
fuente
1
No usaste ningún Objeto dinámico. Solo usaste objetos fuertemente tipados. Por favor, mire en CLR y DLR las diferencias entre los dos.
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
fuente
También puede usar la anotación JsonProperty y deserializar su objeto JSON en una 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 el
1

Use IList para obtener el Conteo JArray y Use Loop para Convertir en 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
fuente