Implement JSON Merge Patch in ASP.NET Core WebAPI

I am interested in adding support for partial updates to my ASP.NET Core WebAPI, where I only update the properties of the resource provided by the caller, leaving the excluded properties unchanged.

For context, imagine that I have a resource that can be described as follows:

GET /users/1 { title: "Mister", firstName: "Frederick", middleName: "McFeely", lastName: "Rodgers" } 

If I wanted to allow consumers to change the value stored in the firstName property from Frederick to Fred individually, I would have to provide a PATCH endpoint that supports JSON Merge Patch Content-Type , for example:

 PATCH /users/1 Content-Type: application/merge-patch+json { firstName: "Fred" } 

However, I see no easy way to find out that firstName is the only property that is being updated. For example, if I were to create a controller that accepted the verbs PATCH , it could be faked as follows:

 [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; } } 

But I don’t see how I can extract which properties had keys defined in the JSON object before it was hydrated as User and passed to my controller. I cannot assume that null means that the property has been excluded, since the caller may explicitly specify the optional null property.

Edit

I know the Microsoft.AspNetCore.JsonPatch library. This, unfortunately, expects the caller to use "[change description]" to determine a PATCH , as described in RFC 5789 , which I find unintuitive and verbose. I mean the "JSON Merge Patch" defined in RFC 7396 .

+5
source share
3 answers

It looks like you will have to wait for odata support for the merge patch.

It is currently in beta and supports the semantics of merging with the Delta <> class.

https://www.nuget.org/packages/Microsoft.AspNetCore.OData/

+1
source

To create a patch you need to define a PatchDocument.

You can find more about this in PatchDocument.

An example of a method.

  [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. } 

Sample document.

 [ { "op": "replace", "path": "/firstName", "value": "boo" }, ] 

This will update the firstName field to 'boo' in the user model.

0
source

Source: https://habr.com/ru/post/1271782/


All Articles