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

我是编程的新手,我不确定这是否可行。工作示例的任何帮助将不胜感激。

Answers:


480

只是调用array.ToObject<List<SelectableEnumItem>>()方法。它将返回您所需要的。

文档:将JSON转换为类型


4
确保您的类定义包括无参数构造函数。
浮士德

1
那么如何处理数组是否为空字段呢?这次我收到错误JsonSerializationException。我想要数据,并且我希望它对于任何null数据都保持为null。
Ensar Turkoglu

1
@nsarchar您是否检查过您的财产可为空?
Jannik '18

@realPro刚刚为我工作。您确定您有一个数组,并且该JArray中的JObjects可以正确映射吗?
VSO

您还会看到此错误,如果您不小心使用了非通用JsonConvert.DeserializeObject(value)而不是JsonConvert.DeserializeObject<T>(value)
Chad Hedgcock

42

问题中的示例是一个更简单的情况,其中属性名称在json和代码中完全匹配。如果属性名称不完全匹配,例如json中"first_name": "Mark"的property和代码中的属性,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 '18

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

1

使用IList获取JArray计数并使用循环转换为列表

       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());             
            }                         
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.