แปลง 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; }
    }

ฉันค่อนข้างใหม่สำหรับการเขียนโปรแกรมและฉันไม่แน่ใจว่ามันเป็นไปได้ ความช่วยเหลือเกี่ยวกับตัวอย่างการทำงานใด ๆ จะได้รับการชื่นชมอย่างมาก

คำตอบ:


480

เพียงแค่เรียกarray.ToObject<List<SelectableEnumItem>>()วิธีการ มันจะคืนสิ่งที่คุณต้องการ

เอกสารประกอบ: แปลง JSON เป็นประเภท


4
ต้องแน่ใจว่าคำจำกัดความของคลาสของคุณมีตัวสร้างแบบไม่มีพารามิเตอร์
เฟาสต์

1
ดังนั้นวิธีการจัดการถ้าอาร์เรย์มีฟิลด์เป็นโมฆะ? คราวนี้ฉันได้รับข้อผิดพลาด JsonSerializationException ฉันต้องการข้อมูลและฉันต้องการให้เป็นโมฆะสำหรับข้อมูลใด ๆ
Ensar Turkoglu

1
@nsarchar คุณได้ตรวจสอบว่าทรัพย์สินของคุณเป็นโมฆะหรือไม่?
Jannik

@realPro เพิ่งใช้งานได้สำหรับฉัน คุณแน่ใจหรือไม่ว่ามีอาร์เรย์และ JObjects ใน JArray นั้นสามารถแมปได้อย่างถูกต้องหรือไม่
VSO

คุณจะเห็นข้อผิดพลาดนี้หากคุณใช้ไม่ใช่แบบทั่วไปโดยไม่ได้ตั้งใจJsonConvert.DeserializeObject(value)แทนJsonConvert.DeserializeObject<T>(value)
Chad Hedgcock

42

ตัวอย่างในคำถามเป็นกรณีที่ง่ายกว่าที่ชื่อคุณสมบัติตรงกันใน json และในรหัส หากชื่อคุณสมบัติไม่ตรงกันทั้งหมดเช่นคุณสมบัติใน json คือ"first_name": "Mark"และคุณสมบัติในรหัสให้FirstNameใช้วิธีการเลือกดังนี้

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 #
Anthony McGrath

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

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());             
            }                         
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.