ฉันจะแจกแจงผ่าน JObject ได้อย่างไร


111

ฉันกำลังพยายามหาวิธีเข้าถึงข้อมูลที่อยู่ใน JObject ของฉันและฉันไม่สามารถกำหนดวิธีการใช้งานได้ตลอดชีวิต

JObject Object = (JObject)Response.Data["my_key"];

ฉันสามารถพิมพ์ลงในคอนโซลโดยใช้ Console.WriteLine (Object) และฉันเห็นข้อมูลดูเหมือนว่า:

{
 "my_data" : "more of my string data"
...
}

แต่ฉันไม่รู้ว่าจะย้ำ / แจกแจงผ่านมันได้อย่างไรใครมีความคิดบ้าง? ตอนนี้ฉันกำลังสูญเสีย

คำตอบ:


167

ถ้าคุณดูที่เอกสารสำหรับJObjectIEnumerable<KeyValuePair<string, JToken>>คุณจะเห็นว่ามันนำไปปฏิบัติ ดังนั้นคุณสามารถทำซ้ำได้โดยใช้foreach:

foreach (var x in obj)
{
    string name = x.Key;
    JToken value = x.Value;
    
}

3
สิ่งนี้ถูกต้อง แต่ด้วยเหตุผลที่ฉันไม่เข้าใจคุณไม่สามารถใช้กับ Linq ได้เว้นแต่คุณจะระบุประเภทที่ระบุไว้อย่างชัดเจน คือคุณ ((IEnumerable<KeyValuePair<string, JToken>>)obj).Select(...)แทนธรรมดาเก่าobj.Select(...); หรืออย่างน้อยนั่นคือสิ่งที่ฉันพบมันเป็นส่วนหนึ่งของรหัสของฉัน
Adrian Ratnapala

2
@AdrianRatnapala obj ของคุณประกาศแบบไดนามิกหรือไม่? วิธีการขยาย (เช่น Enumerable เลือก) ใช้ไม่ได้
svick

1
ไม่ในกรณีของฉันobjมีประเภทJObject; แต่ดูเหมือนว่าจะมีปัญหาคล้ายกับJObject dynamicคอมไพเลอร์ไม่สามารถอนุมานประเภทอาร์กิวเมนต์.Selectได้ ฉันสามารถให้พวกเขาอย่างชัดเจนและobj.Select<KeyValuePair<string, JToken>, (result type)>(...)ใช้ได้ผลกับฉันด้วย
Adrian Ratnapala

3
@AdrianRatnapala อืมคุณพูดถูก เป็นเพราะJObjectใช้ทั้งIEnumerable<KeyValuePair<string, JToken>>และIEnumerable<JToken>(ทางอ้อมผ่านJContainer)
svick

3
ตอนนี้ฉันจะใช้มันสำหรับ JSON ที่ซ้อนกันได้อย่างไร ตัวอย่างเช่นหาก "ค่า" มีคู่คีย์: ค่าอีกชุดหนึ่งฉันจะใช้JToken valueเพื่อวนซ้ำผ่านคู่ชุดถัดไปได้อย่างไร
AlbatrossCafe

53

JObjectsสามารถแจกแจงผ่านวัตถุJProperty ได้โดยการส่งไปยังJToken :

foreach (JProperty x in (JToken)obj) { // if 'obj' is a JObject
    string name = x.Name;
    JToken value = x.Value;
}

หากคุณมี JObject ที่ซ้อนอยู่ภายใน JObject อื่นคุณไม่จำเป็นต้องแคสต์เพราะ accessor จะส่งคืน JToken:

foreach (JProperty x in obj["otherObject"]) { // Where 'obj' and 'obj["otherObject"]' are both JObjects
    string name = x.Name;
    JToken value = x.Value;
}

3
นอกจากนี้คุณยังสามารถอำนวยความสะดวกใช้ LINQ obj.Properties().Select(p => p.Name + ": " + p.Value)ชอบโดย:
itslittlejohn

นี่คือข้อมูลที่ฉันกำลังมองหา ขอบคุณมาก!
jhoepken

15

คำตอบไม่ได้ผลสำหรับฉัน ฉันไม่รู้ว่ามันได้รับการโหวตมากมายขนาดนี้ได้อย่างไร แม้ว่ามันจะช่วยชี้ทิศทางให้ฉัน

นี่คือคำตอบที่เหมาะกับฉัน:

foreach (var x in jobj)
{
    var key = ((JProperty) (x)).Name;
    var jvalue = ((JProperty)(x)).Value ;
}

1
ด้วยสิ่งนั้น (หลังจากบรรทัดนี้: JObject priceComplianceJson = JObject.Parse (File.ReadAllText (fullPath));) ฉันได้รับ "ไม่สามารถแปลงประเภท 'System.Collections.Generic.KeyValuePair <string, Newtonsoft.Json.Linq.JToken>' ถึง 'Newtonsoft.Json.Linq.JProperty' "การถอดงานแคสต์ออกแม้ว่า: var key = x.Key; var jvalue = x.Value; - อย่างน้อยก็รวบรวม ... ฉันจะเช็กฟังก์ชันการทำงานในวันพรุ่งนี้
บีเคลย์แชนนอน

3

สำหรับคนอย่างฉันผู้เสพติด linqและจาก คำตอบของ svickนี่คือแนวทางของ linq:

using System.Linq;
//...
//make it linq iterable. 
var obj_linq = Response.Cast<KeyValuePair<string, JToken>>();

ตอนนี้คุณสามารถสร้างนิพจน์ linq เช่น:

JToken x = obj_linq
          .Where( d => d.Key == "my_key")
          .Select(v => v)
          .FirstOrDefault()
          .Value;
string y = ((JValue)x).Value;

หรือเพียงแค่:

var y = obj_linq
       .Where(d => d.Key == "my_key")
       .Select(v => ((JValue)v.Value).Value)
       .FirstOrDefault();

หรือสิ่งนี้เพื่อวนซ้ำข้อมูลทั้งหมด:

obj_linq.ToList().ForEach( x => { do stuff } ); 
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.