Làm cách nào để liệt kê thông qua JObject?


110

Tôi đang cố gắng xác định cách truy cập vào dữ liệu trong JObject của mình và tôi không thể xác định cách sử dụng nó.

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

Tôi có thể in nó ra bảng điều khiển bằng Console.WriteLine (Đối tượng) và tôi thấy dữ liệu, nó trông giống như:

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

Nhưng tôi KHÔNG có ý tưởng làm thế nào để chỉ lặp lại / liệt kê qua nó, bất cứ ai có bất kỳ ý tưởng nào? Tôi đang rất mất mát ngay bây giờ.

Câu trả lời:


166

Nếu bạn nhìn vào tài liệu choJObject , bạn sẽ thấy rằng nó thực hiện IEnumerable<KeyValuePair<string, JToken>>. Vì vậy, bạn có thể lặp lại nó đơn giản bằng cách sử dụng foreach:

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

3
Điều này đúng, nhưng vì những lý do tôi không hiểu, bạn không thể sử dụng nó với Linq trừ khi bạn truyền rõ ràng sang kiểu liệt kê. Tức là bạn ((IEnumerable<KeyValuePair<string, JToken>>)obj).Select(...)thay vì cũ kỹ obj.Select(...); hoặc ít nhất đó là những gì tôi tìm thấy nó là một phần trong mã của tôi.
Adrian Ratnapala

2
@AdrianRatnapala Đối tượng của bạn có được khai báo là động không? Các phương thức mở rộng (như Enumerable.Select) không hoạt động với điều đó.
svick

1
Không, trong trường hợp của tôi objcó loại JObject; nhưng JObjectdường như có vấn đề tương tự với dynamic. Trình biên dịch không thể suy ra các đối số kiểu .Select. Tôi có thể cung cấp cho họ explictly, obj.Select<KeyValuePair<string, JToken>, (result type)>(...)cũng làm việc cho tôi
Adrian Ratnapala

3
@AdrianRatnapala Hmm, bạn nói đúng. Đó là bởi vì JObjectthực hiện cả hai IEnumerable<KeyValuePair<string, JToken>>IEnumerable<JToken>(gián tiếp thông qua JContainer).
svick

3
Bây giờ tôi làm cách nào để sử dụng nó cho JSON lồng nhau? Ví dụ: nếu "giá trị" chứa một tập hợp các cặp khóa: giá trị khác, làm cách nào tôi có thể sử dụng tập hợp JToken valueđể lặp lại qua tập các cặp tiếp theo?
AlbatrossCafe

53

Các JObject có thể được liệt kê thông qua các đối tượng JProperty bằng cách truyền nó tới một JToken :

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

Nếu bạn có một JObject lồng nhau bên trong một JObject khác, bạn không cần ép kiểu vì trình truy cập sẽ trả về một JToken:

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

3
Bạn cũng có thể thuận tiện sử dụng LINQ như vậy: obj.Properties().Select(p => p.Name + ": " + p.Value).
itlittlejohn

Đây chính xác là thông tin tôi đang tìm kiếm. Cảm ơn bạn rất nhiều!
jhoepken

15

Câu trả lời không phù hợp với tôi. Tôi không biết làm thế nào nó nhận được nhiều phiếu bầu như vậy. Mặc dù nó đã giúp chỉ cho tôi một hướng.

Đây là câu trả lời phù hợp với tôi:

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

1
Với điều đó (sau dòng này: JObject priceComplianceJson = JObject.Parse (File.ReadAllText (fullPath));) Tôi nhận được, "Không thể chuyển đổi loại 'System.Collections.Generic.KeyValuePair <string, Newtonsoft.Json.Linq.JToken>' thành 'Newtonsoft.Json.Linq.JProperty' "Loại bỏ các công việc truyền, mặc dù: var key = x.Key; var jvalue = x.Value; - ít nhất thì nó cũng biên dịch ... Tôi sẽ sửa chức năng vào ngày mai.
B. Clay Shannon,

3

Đối với những người như tôi, những người nghiện linq , và dựa trên câu trả lời của svick , đây là một cách tiếp cận linq:

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

Bây giờ bạn có thể tạo các biểu thức linq như:

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

Hoặc chỉ:

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

Hoặc cái này để lặp lại trên tất cả dữ liệu:

obj_linq.ToList().ForEach( x => { do stuff } ); 
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.