我正在尝试使用JsonPatchDocument替换列表中的对象,但是当我尝试使用正确的路径访问集合的成员时会出现异常,这是我的代码:
var oppfour = new Operation<Application>("replace", "/comments/0", "", obj);
var contractResolver = new DefaultContractResolver();
var operations = new List<Operation<Application>>();
operations.Add(operation);
operations.Add(opptwo);
operations.Add(oppthree);
operations.Add(oppfour);
var patchJson = new JsonPatchDocument<Application>(operations, contractResolver);
try
{
patchJson.ApplyTo(app);
}
我试图访问的数据模型对于Application来说是这样的:
public class Application: BaseEntity
{
public virtual ICollection<Comment> Comments { get; set; }
}
以下是例外:
Microsoft.AspNetCore.JsonPatch.Exceptions.JsonPatchException:The 找不到路径段“0”指定的目标位置。
如何设置替换集合中特定点的内容的路径?
答案 0 :(得分:1)
一个古老的问题,但是... JsonPatch指出它需要确定的路径才能对元素进行操作。对于数组,这意味着为成员指定要更新的序数(或为添加指定“-”)。在幕后,JsonPatchDocument实现了一个列表适配器,以解决从路径更新的项目。为了确定是否应应用列表适配器,它将检查可以转换为IList的所有内容。
现在有了EF,通常可以将子集合实现为ICollection:
public virtual ICollection<ChildObject> Children { get; set; }
但是,如果我们看一下继承,我们会发现IList实现了ICollection,后者实现了IEnumerable。这是有关该主题的快速阅读: https://medium.com/@kunaltandon.kt/ienumerable-vs-icollection-vs-ilist-vs-iqueryable-in-c-2101351453db
但是归结为IList添加了JsonPatch所需的整数索引。因此,无法在ICollection上获取序数。故事结束。
现在,如果您将子集合实现为List或IList,EF就不会抱怨-只要它支持ICollection,EF很高兴您可以毫无问题地应用JsonPatch。但是,要考虑的一件事是,除非您专门发出有序查询,否则您的结果应被视为不确定的。因此,应用整数索引是一个谎言。
如果您进行适当的数据库设计并将键和索引放在表上,则概率是,这只会是一个肮脏的小谎言,而不是丑闻。但这就是您的要求。
答案 1 :(得分:0)
您发送的操作json中的路径不是url路径,而是目标实体的属性(如jobject中的路径),应将操作应用于该属性。
替换:
{ "op": "replace", "path": /comments/0" "value": "..." }
具有:
{ "op": "replace", "path": "propertyname", "value": "propertyvalue" }
,然后通过url定位实体: