使用Json.NET使用新的部分JSON数据修改现有对象
考虑下面的示例程序
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);
Patch()
方法的结果应该等于calendar
除非由patch
更改。 这意味着; Id
将保持不变, CoffeeProvider
将设置为null
, Meetings
将包含位于Room3中的单个项目。
-
如何创建一个通用的
Patch()
方法,该方法适用于Json.NET可反序列化的任何对象(不仅仅是示例Calendar对象)? -
如果(1)这是不可行的,会有什么限制使其可行以及如何实施?
您需要JsonSerializer.Populate()
或其静态包装器方法JsonConvert.PopulateObject()
:
将JSON值填充到目标对象上。
例如,这里是更新Calendar
类的实例:
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 obj, string patch) { var serializer = new JsonSerializer(); using (var reader = new StringReader(patch)) { serializer.Populate(reader, obj); } } }
并且产生的调试输出是:
{ "id": 42, "coffeeprovider": null, "meetings": [ { "location": "Room3", "from": "2014-01-01T04:00:00+00:00", "to": "2014-01-01T05:00:00+00:00" } ] }
更新
如果你想先复制,你可以这样做:
public static T CopyPatch(T obj, string patch) { var serializer = new JsonSerializer(); var json = JsonConvert.SerializeObject(obj); var copy = JsonConvert.DeserializeObject (json); using (var reader = new StringReader(patch)) { serializer.Populate(reader, copy); } return copy; }