struggling with the following, using this example:
I am having a controller with patch operation that takes as a parameter a
JsonPatchDocument patch
then pretty much applying the patch to a dynamic (expando) object similar to the example
patch.ApplyTo(obj);
but unfortunately the ApplyTo(obj)
dies with this following error:
StatusCode = 500, Message = For operation 'replace', the target location specified by path '/updateuser/value' was not found
The path in the operation json you send is not the url-path, it is the property of your target entity.
replace:
{"op":"replace","path":"/updateuser/value","value":"12345"}
with:
{ "op": "replace", "path": "propertyname", "value": "propertyvalue" }
Scenario:
Let’s say we have conference site and attendee want to update a review they gave earlier to a speaker. In this situation, we have a review object that attendee want to update and here we only need to update review section so let’s use JSON Patch to perform this task.
There are multiple approaches to perform patch operation. Here are simple two way.
Sending JsonPatchDocument object as a parameter Creating JsonPatchDocument at runtime We will see this two approach in this article. For now let’s see some code.
I have created “PatchReview” action inside SpeakerController and decorated it with [HTTPPATCH] attribute.
[Route("api/[controller]")]
public class SpeakerController : Controller
{
[HttpPatch("{reviewId}")]
public IActionResult PatchReview([FromBody] JsonPatchDocument<SpeakerReview> patchDocument)
{
if (patchDocument == null)
{
return BadRequest();
}
//In your application get speaker review object from database base on review Id
var speakerFromDb = new SpeakerReview { ReviewId = 2, SpeakerId = 101, Rate = 2.5M, Review = "Good speaker.", ReviewDate = DateTime.UtcNow.AddDays(-1)};
//Apply changes to speaker object
patchDocument.ApplyTo(speakerFromDb);
//update speaker in database and return updated object
return Ok(speakerFromDb);
}
}
This method accept parameter/object of type JsonPatchDocument from request body, then we are getting actual review object that need to update based on requested reviewId but for demo purpose, we are creating dummy SpeakerReview object which we assume is an actual object and applying patch to that object and lastly returning updated review. In reality, a scenario will be different like testing null condition, saving review after patching etc. etc..
Second approach:
In above action, I am passing an actual JsonPatchDocument object as a parameter so you need to remember the actual format of Patch document but if you don”t want to remember those format then you can use built in corresponding operation methods to create JsonPatchDocument at runtime.
Let”s see an example of second approach. If you dig into JsonPatchDocument class there is Replace method where you have to pass path i.e. targeted property/properties of SpeakerReview object and new value then it will return JsonPatchDocument object which is equivalent to an object you passed as a parameter of the first approach. Now you can apply that patch document to a targeted object with help of ApplyTo method. Methods are available for all JSON Patch operation to create JsonPatchDocument object.
//Creating JsonPatchDocument
//Result: [{"op":"replace", "path":"/review", "value":"Good Speaker. I like presentation Style."}]
var jsonPatch = new JsonPatchDocument<SpeakerReview>().Replace(x => x.Review, "Good Speaker. I like presentation Style.");
//In your application get speaker review object from database base on review Id
var speakerFromDb = new SpeakerReview
{
ReviewId = 2,
SpeakerId = 101,
Rate = 2.5M,
Review = "Good speaker.",
ReviewDate = DateTime.UtcNow.AddDays(-1)
};
//Apply changes to speaker object
jsonPatch.ApplyTo(speakerFromDb);
//update speaker in database and return updated object
return Ok(speakerFromDb);
That”s all for patching logic. Let”s see how to call this API from POSTMAN:
Note: This step is valid only if you used the first technique.
Change request type to PATCH and prepare JSON object in the body. Make sure that it is in JSON Patch document format. Here we are only replacing review so i am passing single operation object inside operation array but you can pass multiple operation and it will executes sequentially.
So basically with this JSON Patch document, I am sending a command to replace old value of review property with new value.
Tip: Make sure that your patch request header contains Content-Type of “application/json-patch+json” MIME else your request end up with 415 Unsupported Media Type status code.
Let’s put BreakPoint in patch action and hit that send button.
Here you can compare the value of review property on old and newly patched SpeakerReview object. In the real application, now you need to perform a remaining task but here i am returning updated object.
You can try with the second approach and it will result same as above.
And this is updated SpeakerReview object as a response.
That’s it. This is how we can implement JSON Patch in AspNet Core application. Read JSON Patch spec at least once before starting working with JSON Patch (takes 30 min max) would be good first move. You can find really good examples of different operation at last of spec.
I hope this helps you to get started with JSON Patch in AspNet Core.