2014-12-16 16 views
13

Hãy xem xét ví dụ dưới đây chương trìnhSửa đối tượng hiện với dữ liệu JSON một phần mới sử dụng Json.NET

var calendar = new Calendar 
{ 
    Id = 42, 
    CoffeeProvider = "Espresso2000", 
    Meetings = new[] 
    { 
     new Meeting 
     { 
      Location = "Room1", 
      From = DateTimeOffset.Parse("2014-01-01T00:00:00Z"), 
      To = DateTimeOffset.Parse("2014-01-01T01:00:00Z") 
     }, 
     new Meeting 
     { 
      Location = "Room2", 
      From = DateTimeOffset.Parse("2014-01-01T02:00:00Z"), 
      To = DateTimeOffset.Parse("2014-01-01T03:00:00Z") 
     }, 
    } 
}; 

var patch = @"{ 
     'coffeeprovider': null, 
     'meetings': [ 
      { 
       'location': 'Room3', 
       'from': '2014-01-01T04:00:00Z', 
       'to': '2014-01-01T05:00:00Z' 
      } 
     ] 
    }"; 

var patchedCalendar = Patch(calendar, patch); 

Kết quả của phương pháp Patch() nên bằng calendar trừ khi được thay đổi bằng cách patch. Điêu đo co nghia la; Id sẽ không thay đổi, CoffeeProvider sẽ được đặt thành nullMeetings sẽ chứa một mục duy nhất nằm trong Room3.

  1. Làm sao người ta tạo ra một Patch() phương pháp chung mà sẽ làm việc cho bất kỳ đối tượng (không chỉ là đối tượng dụ Lịch) deserializable bởi Json.NET?

  2. Nếu (1) điều này là không khả thi, thì một số hạn chế nào có thể làm cho nó khả thi và nó sẽ được triển khai như thế nào?

+1

Có lẽ tôi đã hiểu nhầm câu hỏi. Bạn có muốn sửa đổi đối tượng của bạn, hoặc sao chép nó và sửa đổi bản sao? – dbc

+0

Sửa đổi thực sự hoạt động tốt nhất trong kịch bản của tôi. Tuy nhiên, nếu có được xây dựng trong chức năng cho nhân bản tôi sẽ không nhớ làm thế nào để làm điều đó là tốt. Nếu không có chức năng tích hợp sẵn, tôi chỉ có thể sao chép sâu đối tượng (ví dụ: bằng cách tuần tự hóa + deserializing) trước khi vá nó. – Linus

+1

nhân bản sâu thông qua Json.Net là những gì tôi sẽ đề nghị. Đã cập nhật câu trả lời với một mẫu thử nghiệm. – dbc

Trả lời

15

Bạn muốn JsonSerializer.Populate() hoặc phương pháp wrapper tĩnh của nó JsonConvert.PopulateObject():

populates các giá trị JSON vào đối tượng mục tiêu.

Ví dụ, ở đây nó được cập nhật một thể hiện của lớp Calendar của bạn:

public static class TestPopulate 
{ 
    public static void Test() 
    { 
     var calendar = new Calendar 
     { 
      Id = 42, 
      CoffeeProvider = "Espresso2000", 
      Meetings = new[] 
      { 
       new Meeting 
       { 
        Location = "Room1", 
        From = DateTimeOffset.Parse("2014-01-01T00:00:00Z"), 
        To = DateTimeOffset.Parse("2014-01-01T01:00:00Z") 
       }, 
       new Meeting 
       { 
        Location = "Room2", 
        From = DateTimeOffset.Parse("2014-01-01T02:00:00Z"), 
        To = DateTimeOffset.Parse("2014-01-01T03:00:00Z") 
       }, 
      } 
     }; 

     var patch = @"{ 
    'coffeeprovider': null, 
    'meetings': [ 
     { 
      'location': 'Room3', 
      'from': '2014-01-01T04:00:00Z', 
      'to': '2014-01-01T05:00:00Z' 
     } 
    ] 
}"; 
     Patch(calendar, patch); 

     Debug.WriteLine(JsonConvert.SerializeObject(calendar, Formatting.Indented)); 
    } 

    public static void Patch<T>(T obj, string patch) 
    { 
     var serializer = new JsonSerializer(); 
     using (var reader = new StringReader(patch)) 
     { 
      serializer.Populate(reader, obj); 
     } 
    } 
} 

Và kết xuất debug sản xuất là:

{ 
    "id": 42, 
    "coffeeprovider": null, 
    "meetings": [ 
    { 
     "location": "Room3", 
     "from": "2014-01-01T04:00:00+00:00", 
     "to": "2014-01-01T05:00:00+00:00" 
    } 
    ] 
} 

Cập nhật

Nếu bạn muốn sao chép trước, bạn có thể làm:

public static T CopyPatch<T>(T obj, string patch) 
    { 
     var serializer = new JsonSerializer(); 

     var json = JsonConvert.SerializeObject(obj); 
     var copy = JsonConvert.DeserializeObject<T>(json); 

     using (var reader = new StringReader(patch)) 
     { 
      serializer.Populate(reader, copy); 
     } 

     return copy; 
    } 
Các vấn đề liên quan