JSON补丁更新嵌套对象
Posted
技术标签:
【中文标题】JSON补丁更新嵌套对象【英文标题】:JSON Patch update nested object 【发布时间】:2021-01-10 20:26:41 【问题描述】:我一直在尝试使用 JSON Patch 在嵌套对象中使用替换值,但是我觉得我没有得到正确的表示法。任何想法应该是什么路径?
我在LINQPad 6 中创建了以下代码来证明它。
void Main()
var patchTest = new PatchTest();
patchTest.Create();
patchTest.ToString().Dump("Before Patch");
var patch = JsonConvert.DeserializeObject<JsonPatchDocument<Contact>>(
@"[
""op"": ""replace"",
""path"": ""/firstname"",
""value"": ""Benjamin""
,
""op"": ""replace"",
""path"": ""age"",
""value"": ""29""
,
""op"": ""replace"",
""path"": ""//Appointment//Name"",
""value"": ""fsdfdsf""
,
]");
patchTest.Patch(patch);
patchTest.ToString().Dump("After Patch");
public class PatchTest
public Contact Contact get; set;
public PatchTest()
public void Create()
Contact = new Contact
FirstName = "Walt",
LastName = "Banks",
Age = 20
;
public void Patch(JsonPatchDocument<Contact> patch)
patch.Replace(e => e.Appointment, Contact.Appointment);
patch.ApplyTo(Contact);
public override string ToString()
return $"nameof(Contact): Contact";
public class Contact
public string FirstName get; set;
public string LastName get; set;
public int Age get; set;
public Appointment Appointment get; set;
public override string ToString()
return $"nameof(FirstName): FirstName, nameof(LastName): LastName, nameof(Appointment): Appointment";
public class Appointment
public string Name get; set;
public override string ToString()
return $"nameof(Name): Name";
但是找不到名字
【问题讨论】:
【参考方案1】:找不到约会名称的原因是因为您在创建Contact
时没有初始化Appointment
。将Create
更改为:
public void Create()
Contact = new Contact
FirstName = "Walt",
LastName = "Banks",
Age = 20,
Appointment = new Appointment()
;
现在在控制台应用程序中运行您的示例会产生以下输出:
Before Patch
Contact: FirstName: Walt, LastName: Banks, Age: 20, Appointment: Name:
After Patch
Contact: FirstName: Benjamin, LastName: Banks, Age: 29, Appointment: Name: fsdfdsf
我将Contact.Age
添加到其ToString()
覆盖中,因为它丢失了。此外,单 /
和双 //
都在路径中工作。我猜你在试图找出问题所在时使用了后者。
现在,由于您已经在 JSON 中定义了文档,因此您不需要定义另一个替换操作。您的Patch
方法可以简化为:
public void Patch(JsonPatchDocument<Contact> patch)
patch.ApplyTo(Contact);
并且输出将与以前相同。相当于在代码中完成所有这些操作,而无需手动创建 JSON 文档,如下所示:
public void Patch(Contact amendedContact)
var patch = new JsonPatchDocument<Contact>();
patch.Replace(e => e.FirstName, amendedContact.FirstName);
patch.Replace(e => e.Age, amendedContact.Age);
patch.Replace(e => e.Appointment.Name, amendedContact.Appointment.Name);
patch.ApplyTo(Contact);
这样称呼它:
var amendedContact = new Contact
FirstName = "Benjamin",
Age = 29,
Appointment = new Appointment
Name = "fsdfdsf"
;
patchTest.Patch(amendedContact);
这又会产生您想要的输出。但是您仍然必须确保初始化嵌套属性,否则您将遇到原始问题。
【讨论】:
【参考方案2】:您正在尝试为未初始化的Appointment
上的Name
属性设置值。创建新实例时更新Contact
类以初始化属性:
public class Contact
public Contact()
Appointment = new Appointment();
...
根据经验,您应该尝试初始化所有类似的属性,以确保其他类不会发生类似的问题。
【讨论】:
以上是关于JSON补丁更新嵌套对象的主要内容,如果未能解决你的问题,请参考以下文章
在 ASP.NET Core WebAPI 中实现 JSON 合并补丁