2015-09-28 14 views
5

Tôi kết nối với dịch vụ web bên thứ ba trả về một đối tượng JSON phức tạp chỉ chứa một vài thông tin tôi thực sự cần.Chọn lọc đọc một phần dữ liệu JSON bằng cách sử dụng JsonSerializer và điền một đối tượng C#

Về cơ bản, tôi chỉ cần mảng trong "giá trị". Từ mảng đó, tôi chỉ cần các thuộc tính "Id", "Tiêu đề" và "Trạng thái".

Tôi muốn đặt các thuộc tính đó vào một lớp C# được gọi là Dự án. Đây là lớp học của tôi:

public class Project 
{ 
    public String Id { get; set; } 
    public String Title { get; set; } 
    public String Status { get; set; } 
} 

Tôi đang cố gắng sử dụng mã này để đọc các JSON và làm biến đổi:

using (WebResponse response = request.GetResponse()) 
{ 
    using (StreamReader reader = new StreamReader(response.GetResponseStream())) 
    { 
     var serializer = new JsonSerializer(); 
     var jsonTextReader = new JsonTextReader(reader); 
     returnValue = serializer.Deserialize<Project>(jsonTextReader); 
    } 
} 

Ví dụ JSON:

{ 
    "odata.metadata":"http://school.edu/Api/1/$metadata#Projects", 
    "odata.count":"3", 
    "value":[ 
     { 
      "odata.id":"http://school.edu/Api/1/Projects('123')", 
      "[email protected]":"http://school.edu/Api/1/Projects('123')/RelatedProjects", 
      "[email protected]":"http://school.edu/Api/1/Projects('123')/Tags", 
      "[email protected]":"http://school.edu/Api/1/Projects('123')/Categories", 
      "[email protected]":"http://school.edu/Api/1/Projects('123')/ep", 
      "#CreateLike":{ 
        "target":"http://school.edu/Api/1/Projects('123')/CreateLike" 
        }, 
      "#CreateShortcut":{ 
         "target":"http://school.edu/Api/1/Projects('123')/CreateShortcut" 
         }, 
      "#Play":{ 
         "target":"http://school.edu/Play/123" 
         }, 
      "#SendInvitation":{ 
         "target":"http://school.edu/Api/1/Projects('123')/SendInvitation" 
         }, 
      "#CopyProject":{ 
         "target":"http://school.edu/Api/1/Projects('123')/CopyProject" 
         }, 
      "#AddVideoPodcast":{ 
         "target":"http://school.edu/Api/1/Projects('123')/AddVideoPodcast" 
         }, 
      "#AddEP":{ 
         "target":"http://school.edu/Api/1/Projects('123')/AddEP" 
         }, 
      "Id":"123", 
      "Title":"Test Title 1", 
      "Status":"Viewable" 
     }, 
     { 
      "odata.id":"http://school.edu/Api/1/Projects('456')", 
      "[email protected]":"http://school.edu/Api/1/Projects('456')/RelatedProjects", 
      "[email protected]":"http://school.edu/Api/1/Projects('456')/Tags", 
      "[email protected]":"http://school.edu/Api/1/Projects('456')/Categories", 
      "[email protected]":"http://school.edu/Api/1/Projects('456')/ep", 
      "#CreateLike":{ 
        "target":"http://school.edu/Api/1/Projects('456')/CreateLike" 
        }, 
      "#CreateShortcut":{ 
         "target":"http://school.edu/Api/1/Projects('456')/CreateShortcut" 
         }, 
      "#Play":{ 
         "target":"http://school.edu/Play/456" 
         }, 
      "#SendInvitation":{ 
         "target":"http://school.edu/Api/1/Projects('456')/SendInvitation" 
         }, 
      "#CopyProject":{ 
         "target":"http://school.edu/Api/1/Projects('456')/CopyProject" 
         }, 
      "#AddVideoPodcast":{ 
         "target":"http://school.edu/Api/1/Projects('456')/AddVideoPodcast" 
         }, 
      "#AddEP":{ 
         "target":"http://school.edu/Api/1/Projects('456')/AddEP" 
         }, 
      "Id":"456", 
      "Title":"Test Title 2", 
      "Status":"Viewable" 
     }, 
     { 
      "odata.id":"http://school.edu/Api/1/Projects('789')", 
      "[email protected]":"http://school.edu/Api/1/Projects('789')/RelatedProjects", 
      "[email protected]":"http://school.edu/Api/1/Projects('789')/Tags", 
      "[email protected]":"http://school.edu/Api/1/Projects('789')/Categories", 
      "[email protected]":"http://school.edu/Api/1/Projects('789')/ep", 
      "#CreateLike":{ 
        "target":"http://school.edu/Api/1/Projects('789')/CreateLike" 
        }, 
      "#CreateShortcut":{ 
         "target":"http://school.edu/Api/1/Projects('789')/CreateShortcut" 
         }, 
      "#Play":{ 
         "target":"http://school.edu/Play/789" 
         }, 
      "#SendInvitation":{ 
         "target":"http://school.edu/Api/1/Projects('789')/SendInvitation" 
         }, 
      "#CopyProject":{ 
         "target":"http://school.edu/Api/1/Projects('789')/CopyProject" 
         }, 
      "#AddVideoPodcast":{ 
         "target":"http://school.edu/Api/1/Projects('789')/AddVideoPodcast" 
         }, 
      "#AddEP":{ 
         "target":"http://school.edu/Api/1/Projects('789')/AddEP" 
         }, 
      "Id":"789", 
      "Title":"Test Title 3", 
      "Status":"Viewable" 
     } 
    ], 
    "odata.nextLink":"http://school.edu/Api/1/Folders('xyz')/Projects?$skip=10&$top=10" 
} 

tôi chỉ nhận được một null đối tượng trở lại. Nhưng trong trình gỡ lỗi, tôi có thể thấy rằng nó đang lấy tất cả dữ liệu JSON từ webservice.

Làm cách nào để có được những gì tôi cần từ JSON, tạo các đối tượng C# của tôi và bỏ qua tất cả các phần còn lại?

THanks!

+1

Đã xem tài liệu Deserialize dường như không có chức năng vốn có cho việc này. Vì vậy, vì lợi ích của việc dành thời gian chờ đợi một câu trả lời có thể bạn không deserialize toàn bộ điều, sau đó chọn lọc sử dụng các thuộc tính mà bạn cần? –

+0

@ m.edmondson cảm ơn. Câu hỏi ngu ngốc, nhưng không có deserializing, làm thế nào tôi sẽ nhận được dữ liệu/thuộc tính tôi cần? – SkyeBoniwell

+1

Bạn không thể deserialize toàn bộ phản ứng? –

Trả lời

5

Nếu bạn có thể sử dụng Json.NET (Newtonsoft json), bạn có thể sử dụng Linq-to-Json như thế này [1]

//using Newtonsoft.Json.Linq; 
var jsonString = File.ReadAllText(@"C:YourDirectory\file.json"); //source 
var projects = new List<Project>(); //Your result 

JObject data = JObject.Parse(jsonString); 
foreach (var value in data["value"]) 
{ 
    projects.Add(new Project 
    { 
     Id = value["Id"].ToString(), 
     Status = value["Status"].ToString(), 
     Title = value["Title"].ToString() 
    }); 
} 

Hoặc, bạn cũng có thể deserialize JObject như thế này [2]

var jsonReader = data["value"].CreateReader(); 
projects = new JsonSerializer().Deserialize<List<Project>>(jsonReader); 

Cả hai đều hoạt động tốt, nhưng cái nào tốt hơn?

Cách tiếp cận thứ hai có nghĩa là ít mã hơn (đặc biệt, nếu bạn có nhiều thuộc tính trong lớp Project, bạn sẽ phải viết nhiều dòng mã để ánh xạ từng thuộc tính trong mã [1]).

Nhưng hiệu suất của phương pháp tiếp cận đầu tiên tốt hơn nhiều lần! Đối với dữ liệu json đã cho, mã [1] chạy gần bằng 1 ms trong khi mã [2] mất hơn 100 ms!


Cập nhật

Sau khi đầu vào từ James Newton-King (người đã viết Json.NET :), có một cách khác, ngay cả thanh lịch hơn để làm điều này [3]

projects = data["value"].ToObject<List<Project>>(); 

Và hãy đoán xem! Mã này [3] mất gần một nửa số thời gian tiếp cận [1]. Vì vậy, từ tất cả các quan điểm, đây phải là cách tiếp cận tốt nhất!

+3

Ví dụ thứ hai của bạn có thể được cải thiện: dữ liệu ["giá trị"]. ToObject >() –

+2

@ JamesNewton-King Ah! Tôi không biết điều đó, cảm ơn. Tôi đã cập nhật câu trả lời của tôi để bao gồm điều đó, và nó cũng cho thấy hiệu suất tốt nhất theo thử nghiệm đồng hồ bấm giờ của tôi :) –

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