JsonPatchDocument访问ICollection

时间:2017-06-15 16:08:57

标签: c# entity-framework patch

我正在尝试使用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”指定的目标位置。

如何设置替换集合中特定点的内容的路径?

2 个答案:

答案 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定位实体:

https://yourapiendpoint/comments/0