Преобразовать Newtonsoft.Json.Linq.JArray в список определенного типа объекта

236

У меня есть следующая переменная типа {Newtonsoft.Json.Linq.JArray}.

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

]}

Что я хочу сделать, это преобразовать это в List<SelectableEnumItem>где SelectableEnumItemследующий тип:

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

Я довольно новичок в программировании, и я не уверен, возможно ли это. Любая помощь с рабочим примером будет принята с благодарностью.

Mdb
источник

Ответы:

481

Просто вызовите array.ToObject<List<SelectableEnumItem>>()метод. Он вернет то, что вам нужно.

Документация: конвертировать JSON в тип

HoberMellow
источник
4
Убедитесь, что ваше определение класса включает конструктор без параметров.
Фауст
1
Так как же справиться, если массив имеет нулевое поле? На этот раз я получаю сообщение об ошибке JsonSerializationException. Я хочу данные, и я хочу, чтобы они оставались нулевыми для любых нулевых данных.
Энсар Тюркоглу
1
@nsarchar Вы проверили, что ваша собственность обнуляется?
Янник
@realPro Просто работал для меня. Вы уверены, что у вас есть массив, и что объекты JObject в этом JArray могут отображаться правильно?
VSO
Вы также увидите эту ошибку, если вы случайно использовали неуниверсальный JsonConvert.DeserializeObject(value)вместоJsonConvert.DeserializeObject<T>(value)
Чад
42

Пример в вопросе является более простым случаем, когда имена свойств точно совпадают в json и в коде. Если имена свойств не полностью совпадают, например, свойство в json is "first_name": "Mark"и свойство в code, FirstNameтогда используйте метод Select следующим образом

List<SelectableEnumItem> items = ((JArray)array).Select(x => new SelectableEnumItem
{
    FirstName = (string)x["first_name"],
    Selected = (bool)x["selected"]
}).ToList();
Сувик Басу
источник
Сэр, этот код получает первое значение из моего ответа, но у меня есть много значений, как я могу получить все значения. Но мне нужно получить только одно значение, я имею в виду, что в ответе есть имя и фамилия. Я хочу получить только имя, как я могу сделай это ?
tpbafk
6

Возвращаемое значение API в моем случае, как показано здесь:

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

Преобразование массива элементов в список клиентов было обработано, как показано здесь:

 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);
        }
Стивен Эбичондо
источник
Спасибо, это сработало для меня, используя динамические объекты в C #
Энтони МакГрат
2

Я могу придумать другой метод для достижения того же

IList<SelectableEnumItem> result= array;

или (у меня была какая-то ситуация, что эта не сработала)

var result = (List<SelectableEnumItem>) array;

или используйте расширение linq

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

или

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

или более явно

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

пожалуйста, обратите внимание, в приведенном выше решении я использовал динамический объект

Я могу придумать еще несколько решений, которые представляют собой комбинации вышеуказанных решений. но я думаю, что он охватывает почти все доступные методы.

Я сам использую первый

Мо Град А
источник
1
Вы не использовали никаких динамических объектов. Вы использовали только строго типизированный объект. Пожалуйста, посмотрите на CLR и DLR для различий между ними.
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;
  }
}
Мохаммед Хоссен
источник
Вы также можете использовать аннотацию JsonProperty и десериализовать ваш объект JSON в список. 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); }
Мохаммед
1

Используйте IList для получения JArray Count и используйте Loop для преобразования в список

       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
источник