2011-01-20 44 views
252

Tôi biết có một vài bài viết về Newtonsoft vì vậy hy vọng điều này không chính xác lặp lại ... Tôi đang cố gắng chuyển đổi dữ liệu JSON được trả về bởi API Kazaa thành một đối tượng tốt đẹp của một số loạiDeserializing JSON để .NET đối tượng bằng cách sử dụng Newtonsoft (hoặc LINQ to JSON có thể?)

WebClient client = new WebClient(); 
Stream stream = client.OpenRead("http://api.kazaa.com/api/v1/search.json?q=muse&type=Album"); 
StreamReader reader = new StreamReader(stream); 

List<string> list = Newtonsoft.Json.JsonConvert.DeserializeObject<List<string>>(reader.Read().ToString()); 

foreach (string item in list) 
{ 
    Console.WriteLine(item); 
} 

//Console.WriteLine(reader.ReadLine()); 
stream.Close(); 

đó JsonConvert dòng chỉ là một trong những gần đây nhất mà tôi đã cố gắng ... tôi không hoàn toàn nhận được nó và đã hy vọng để loại bỏ một số động tác chân bằng cách hỏi các bạn. Ban đầu tôi đã cố gắng chuyển đổi nó thành một từ điển hay một cái gì đó ... và thực sự, tôi chỉ cần snag một vài giá trị trong đó để đánh giá tài liệu, có lẽ LINQ của Newtonsoft có thể là một lựa chọn tốt hơn? Suy nghĩ/Liên kết?

Dưới đây là một ví dụ về dữ liệu JSON trở lại:

{ 
    "page": 1, 
    "total_pages": 8, 
    "total_entries": 74, 
    "q": "muse", 
    "albums": [ 
    { 
     "name": "Muse", 
     "permalink": "Muse", 
     "cover_image_url": "http://image.kazaa.com/images/69/01672812 1569/Yaron_Herman_Trio/Muse/Yaron_Herman_Trio-Muse_1.jpg", 
     "id": 93098, 
     "artist_name": "Yaron Herman Trio" 
    }, 
    { 
     "name": "Muse", 
     "permalink": "Muse", 
     "cover_image_url": "htt p://image.kazaa.com/images/54/888880301154/Candy_Lo/Muse/Candy_Lo-Muse_1.jpg", 
     "i d": 102702, 
     "artist_name": "\u76e7\u5de7\u97f3" 
    }, 
    { 
     "name": "Absolution", 
     "permalink": " Absolution", 
     "cover_image_url": "http://image.kazaa.com/images/65/093624873365/Mus e/Absolution/Muse-Absolution_1.jpg", 
     "id": 48896, 
     "artist_name": "Muse" 
    }, 
    { 
     "name": "Ab solution", 
     "permalink": "Absolution-2", 
     "cover_image_url": "http://image.kazaa.com/i mages/20/825646911820/Muse/Absolution/Muse-Absolution_1.jpg", 
     "id": 118573, 
     "artist _name": "Muse" 
    }, 
    { 
     "name": "Black Holes And Revelations", 
     "permalink": "Black-Holes-An d-Revelations", 
     "cover_image_url": "http://image.kazaa.com/images/66/093624428466/ Muse/Black_Holes_And_Revelations/Muse-Black_Holes_And_Revelations_1.jpg", 
     "id": 48813, 
     "artist_name": "Muse" 
    }, 
    { 
     "name": "Black Holes And Revelations", 
     "permalink": "Bla ck-Holes-And-Revelations-2", 
     "cover_image_url": "http://image.kazaa.com/images/86/ 825646911486/Muse/Black_Holes_And_Revelations/Muse-Black_Holes_And_Revelations_1 .jpg", 
     "id": 118543, 
     "artist_name": "Muse" 
    }, 
    { 
     "name": "Origin Of Symmetry", 
     "permalink": "Origin-Of-Symmetry", 
     "cover_image_url": "http://image.kazaa.com/images/29/825646 912629/Muse/Origin_Of_Symmetry/Muse-Origin_Of_Symmetry_1.jpg", 
     "id": 120491, 
     "artis t_name": "Muse" 
    }, 
    { 
     "name": "Showbiz", 
     "permalink": "Showbiz", 
     "cover_image_url": "http: //image.kazaa.com/images/68/825646182268/Muse/Showbiz/Muse-Showbiz_1.jpg", 
     "id": 60444, 
     "artist_name": "Muse" 
    }, 
    { 
     "name": "Showbiz", 
     "permalink": "Showbiz-2", 
     "cover_imag e_url": "http://image.kazaa.com/images/50/825646912650/Muse/Showbiz/Muse-Showbiz_ 1.jpg", 
     "id": 118545, 
     "artist_name": "Muse" 
    }, 
    { 
     "name": "The Resistance", 
     "permalink": "T he-Resistance", 
     "cover_image_url": "http://image.kazaa.com/images/36/825646864836/ Muse/The_Resistance/Muse-The_Resistance_1.jpg", 
     "id": 121171, 
     "artist_name": "Muse" 
    } 
    ], 
    "per_page": 10 
} 

tôi đã làm một số đọc hơn và tìm thấy LINQ Newtonsoft để JSON là chính xác những gì tôi muốn ... sử dụng WebClient, Stream, StreamReader, và Newtonsoft ... Tôi có thể nhấn Kazaa cho dữ liệu JSON, trích xuất URL, tải xuống tệp và thực hiện tất cả trong bảy dòng mã! Tôi thích nó.

WebClient client = new WebClient(); 
Stream stream = client.OpenRead("http://api.kazaa.com/api/v1/search.json?q=muse&type=Album"); 
StreamReader reader = new StreamReader(stream); 

Newtonsoft.Json.Linq.JObject jObject = Newtonsoft.Json.Linq.JObject.Parse(reader.ReadLine()); 

// Instead of WriteLine, 2 or 3 lines of code here using WebClient to download the file 
Console.WriteLine((string)jObject["albums"][0]["cover_image_url"]); 
stream.Close(); 

bài này được rất nhiều hits Tôi nghĩ rằng nó có thể hữu ích để bao gồm các bit "sử dụng" được thảo luận trong các ý kiến.

using(var client = new WebClient()) 
using(var stream = client.OpenRead("http://api.kazaa.com/api/v1/search.json?q=muse&type=Album")) 
using (var reader = new StreamReader(stream)) 
{ 
    var jObject = Newtonsoft.Json.Linq.JObject.Parse(reader.ReadLine()); 
    Console.WriteLine((string) jObject["albums"][0]["cover_image_url"]); 
} 
+6

Ví dụ về Slick, cảm ơn. Chỉ là một gợi ý: bạn có thể đã tắt điều này một cách ngắn gọn, nhưng vì 'WebClient',' Stream' và 'StreamReader' đều thực hiện' IDisposable', bạn có thể muốn thêm một số khối 'using' vào mã của bạn. – arcain

+0

ah vâng, cuộc gọi tốt ... (ya đây thực sự chỉ là một ứng dụng giao diện điều khiển mà tôi đang chạy thật nhanh để nghiên cứu các tác vụ tôi sắp có) Bây giờ để nghiên cứu đoạn cuối của câu đố, mã hóa HLS + AES :) ugh ...lol –

+1

+1 Cảm ơn bạn đã đăng ví dụ về Linq. Chính xác những gì tôi cần. –

Trả lời

213

Nếu bạn chỉ cần lấy một vài mục từ đối tượng JSON, tôi sẽ sử dụng lớp LINQ to JSON JObject của Json.NET. Ví dụ:

JToken token = JObject.Parse(stringFullOfJson); 

int page = (int)token.SelectToken("page"); 
int totalPages = (int)token.SelectToken("total_pages"); 

Tôi thích phương pháp này vì bạn không cần phải deserialize đối tượng JSON. Điều này có ích với các API đôi khi có thể làm bạn ngạc nhiên với các thuộc tính thiếu đối tượng, như Twitter.

Tài liệu: Serializing and Deserializing JSON with Json.NETLINQ to JSON with Json.NET

+1

ya Tôi đã thực sự đọc nhiều hơn và thử nghiệm ... thấy đây là một cách hay để làm nó ... Newtonsoft, thư viện đẹp, tôi sẽ đăng ví dụ của tôi cho những người khác –

+1

đăng một ví dụ thô về cách tôi đã làm nó ... không hoàn toàn giống nhau, tôi thấy bạn đề nghị JToken.Parse ... không chắc chắn về sự khác biệt giữa hai nhưng nhưng ya, những thứ tốt! –

+0

@Jbenjamin Cảm ơn! Đó là một lỗi đánh máy. JToken là lớp cơ sở cho JObject, và nó chỉ là sở thích cá nhân của tôi để làm việc với kiểu trừu tượng hơn. Cảm ơn vì đã gọi sự chú ý của tôi. – arcain

20

Đúng tôi nếu tôi nhầm, nhưng ví dụ trước, tôi tin rằng, chỉ là một chút không đồng bộ với phiên bản mới nhất của thư viện Json.NET James Newton.

var o = JObject.Parse(stringFullOfJson); 
var page = (int)o["page"]; 
var totalPages = (int)o["total_pages"]; 
+1

cảm ơn câu trả lời của bạn Rick, ya trông giống như các ví dụ tôi tìm thấy trong tài liệu gần đây nhất. –

+1

Vâng, kể từ khi arcain sửa lỗi đánh máy, bình luận của tôi bây giờ chỉ trông có vẻ ngớ ngẩn: '(.Tôi đã đăng vì tôi không nhận ra JToken.Parse. –

+1

Không phải là cực kỳ khó hiểu - chắc chắn * là * một sai lầm, và luôn có nhiều Bằng cách này, phiên bản Json.NET của tôi hỗ trợ cú pháp bằng cách sử dụng trình chỉ mục trên 'JObject', nhưng mã tôi đã sửa đổi cho câu trả lời của tôi đã được lấy từ việc sử dụng mã làm quá tải của' SelectToken 'phương pháp để tôi có thể ngăn chặn ngoại lệ nếu mã thông báo không được tìm thấy:' JToken JToken.SelectToken (chuỗi tokenName, bool errorWhenNoMatch) ', do đó, đó là nơi verbosity đến từ – arcain

219

Bạn có thể sử dụng loại C# dynamic để làm mọi thứ dễ dàng hơn. Kỹ thuật này cũng làm cho việc tái bao thanh toán đơn giản hơn vì nó không dựa vào chuỗi phép thuật.

JSON

Chuỗi JSON dưới đây là một phản ứng đơn giản từ một cuộc gọi API HTTP, và nó định nghĩa hai thuộc tính: IdName.

{"Id": 1, "Name": "biofractal"} 

C#

Sử dụng JsonConvert.DeserializeObject<dynamic>() để deserialize chuỗi này thành một loại động sau đó chỉ cần truy cập vào thuộc tính của nó theo cách thông thường.

dynamic results = JsonConvert.DeserializeObject<dynamic>(json); 
var id = results.Id; 
var name= results.Name; 

Nếu bạn chỉ định kiểu của biến results như dynamic, thay vì sử dụng các từ khóa var, sau đó các giá trị bất động sản sẽ deserialize một cách chính xác, ví dụ Id đến một số int và không phải là JValue (nhờ GFoley83 cho nhận xét bên dưới).

Lưu ý: Liên kết NuGet cho cụm Newtonsoft là http://nuget.org/packages/newtonsoft.json.

+10

+1 Sử dụng 'năng động' là con đường để đi đến đây IMO –

+0

Tôi đã sử dụng cùng một đoạn mã như trên để deserialize các phản ứng twitter với newtonsoft.dll phiên bản 4.5.6 và nó đã làm việc tốt .. nhưng sau khi cập nhật nó lên phiên bản 5.0.6 .. nó bắt đầu ném lỗi .. bất kỳ ý tưởng tại sao ?? – Pranav

+0

Tốt cho đối tượng động, khi chúng ta biết hoặc chúng ta có lớp C# để chúng ta có thể sử dụng như một lớp C# trên thay thế động, ví dụ: . – MSTdev

31

Với từ khóa dynamic, nó trở nên thực sự dễ dàng để phân tích bất kỳ đối tượng của loại hình này:

dynamic x = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonString); 
var page = x.page; 
var total_pages = x.total_pages 
var albums = x.albums; 
foreach(var album in albums) 
{ 
    var albumName = album.name; 

    // Access album data; 
} 
+0

Tôi muốn biết cách lặp qua các kết quả và việc này mất quá nhiều thời gian để tìm ... cảm ơn !! – batoutofhell

7

Ngoài ra, nếu bạn chỉ cần tìm kiếm một giá trị cụ thể lồng trong nội dung JSON bạn có thể làm một cái gì đó như như vậy:

yourJObject.GetValue("jsonObjectName").Value<string>("jsonPropertyName"); 

Và cứ tiếp tục từ đó.

Điều này có thể giúp ích nếu bạn không muốn chịu chi phí chuyển đổi toàn bộ JSON thành đối tượng C#.

10

Deserialize và nhận được giá trị (khi bộ sưu tập là động):

// First serializing 
dynamic collection = new { stud = stud_datatable }; // The stud_datable is the list or data table 
string jsonString = JsonConvert.SerializeObject(collection); 


// Second Deserializing 
dynamic StudList = JsonConvert.DeserializeObject(jsonString); 

var stud = StudList.stud; 
foreach (var detail in stud) 
{ 
    var Address = detail["stud_address"]; // Access Address data; 
} 
4

Tôi thích phương pháp này:

using Newtonsoft.Json.Linq; 
// jsonString is your JSON-formatted string 
JObject jsonObj = JObject.Parse(jsonString); 
Dictionary<string, object> dictObj = jsonObj.ToObject<Dictionary<string, object>>(); 

Bây giờ bạn có thể truy cập bất cứ điều gì bạn muốn bằng cách sử dụng dictObj như một cuốn từ điển. Bạn cũng có thể sử dụng Dictionary<string, string> nếu bạn muốn nhận các giá trị dưới dạng chuỗi.

Bạn có thể sử dụng cùng phương pháp này để truyền dưới dạng bất kỳ loại đối tượng .NET nào.

+1

Tôi thấy phương pháp này rất đẹp vì hai lý do: 1) khi bạn không quan tâm đến kiểu dữ liệu (mọi thứ đều là chuỗi) và 2) thuận tiện khi làm việc với từ điển của các giá trị – netfed

4

Nếu, như tôi, bạn thích để đối phó với các đối tượng mạnh mẽ gõ ** đi với:

MyObj obj = JsonConvert.DeserializeObject<MyObj>(jsonString); 

Bằng cách này bạn có thể sử dụng IntelliSense và biên dịch kiểm tra kiểu lỗi thời gian.

Bạn có thể dễ dàng tạo các đối tượng được yêu cầu bằng cách sao chép JSON vào bộ nhớ và dán nó làm đối tượng JSON (Visual Studio -> Edit -> Paste Special -> Paste JSON as Classes).

Xem here nếu bạn không có tùy chọn đó trong Visual Studio.

Bạn cũng sẽ cần đảm bảo JSON của mình hợp lệ. Thêm đối tượng của riêng bạn ngay từ đầu nếu nó chỉ là một mảng các đối tượng. ví dụ như {"obj": [{}, {}, {}]}

** Tôi biết rằng động làm cho mọi thứ dễ dàng hơn, nhưng đôi khi tôi hơi ol'skool với điều này.

Các vấn đề liên quan