在ASP.NET Core WebAPI中实现JSON Merge修补程序

Tec*_*ium 9 c# asp.net-mvc asp.net-web-api asp.net-core asp.net-core-webapi

我有兴趣在我的ASP.NET核心WebAPI中添加对部分更新的支持,我只更新调用者提供的资源上的属性,保留排除的属性不变.

对于上下文,假设我有一个资源可以描述如下:

GET /users/1
{
    title: "Mister",
    firstName: "Frederick",
    middleName: "McFeely",
    lastName: "Rodgers"
}
Run Code Online (Sandbox Code Playgroud)

如果我想允许消费者将firstName属性中存储的值从"Frederick"单独更改为"Fred",我应该能够公开PATCH支持JSON Merge Patch 的端点Content-Type,如下所示:

PATCH /users/1
Content-Type: application/merge-patch+json
{
    firstName: "Fred"
}
Run Code Online (Sandbox Code Playgroud)

但是,我认为没有简单的方法可以让我知道这firstName是唯一正在更新的属性.例如,如果我要创建一个接受PATCH动词的控制器,它可以像这样搭建:

[Route("users")]
public class UsersController : Controller {

    [HttpPatch("{userId:int}")]
    public User Patch([FromRoute] int userId, [FromBody] User user) {

        // How do I know which properties were set on User at this point?

    }

}

public class User {

    public String Title { get; set; }
    public String FirstName { get; set; }
    public String MiddleName { get; set; }
    public String LastName { get; set; }

}
Run Code Online (Sandbox Code Playgroud)

但是我没有看到如何提取哪些属性'在JSON对象上定义了键,然后将其作为a User并传递给我的控制器.我不能假设一个值null表示属性被排除,因为调用者可以显式地将可选属性设置为null.

编辑

我知道Microsoft.AspNetCore.JsonPatch库.遗憾的是,这需要调用者使用"[change of changes]"来定义RFC 5789中PATCH描述的内容,我发现它不直观且冗长.我指的是RFC 7396中定义的"JSON Merge Patch" .

why*_*eee 6

我找到了一个有效的库:https : //github.com/Morcatko/Morcatko.AspNetCore.JsonMergePatch

[HttpPatch]
[Consumes(JsonMergePatchDocument.ContentType)]
public void Patch([FromBody] JsonMergePatchDocument<Model> patch)
{
    ...
    patch.ApplyTo(backendModel);
    ...
}
Run Code Online (Sandbox Code Playgroud)

或用于patch.JsonPatchDocument.Operations手动遍历补丁请求字段。


Ant*_*jke -3

为了打补丁,你必须定义 PatchDocument。

有关更多信息,您可以找到PatchDocument

方法示例。

 [HttpPatch("{userId:int}")]   
 public IActionResult UserPatch(int userId, [FromBody] JsonPatchDocument<User> patchDocument) {

    var user = new User();
    // Because it comes from url.
    user.Id = userId;
    patchDocument.ApplyTo(user);

    // Here you call context or repository to save.

  }
Run Code Online (Sandbox Code Playgroud)

文档示例。

[
  { "op": "replace", "path": "/firstName", "value": "boo" },
]
Run Code Online (Sandbox Code Playgroud)

这会将用户模型中的firstName 字段更新为“boo”。

  • 你好,谢谢你的回答。不幸的是,您将 [PATCH 的原始想法](https://tools.ietf.org/html/rfc5789) 与我正在寻找的内容混淆:[JSON Merge PATCH](https://tools.ietf.org /html/rfc7396)。它们使用相同的动词,但后者是 RFC 中定义的特定内容类型。 (3认同)