Original link: The Patch Verb in Web API 2 with JSON
I want to be in. NET4.6 in a Web API 2 project using patch to update a word in a large object, it was realized that I had never used patches before. This is a rare opportunity to learn.
I don't know what's the best way to do it in Web API 2, so I followed the convention by using Google to search for "Patch Web API." The first result I got was Michael McKenna's "How to Add JSON Patch for the Web API". It looks as if you can do it, but I want to know why he must write a solution for it. There is no doubt that patch is a very common requirement in the Web API. NET does not have a native way to implement it? Maybe Michael doesn't know.
After some exploration, in almost all of the forums and blogs are not the following three ways, but none of them is my favorite.
1. Write an API for each attribute
It is suggested that you write a method for each modification, such as setting "Book.name", setting "Book.pagecount", and so on. There is no doubt that this approach takes time and is poorly maintained, especially when there are many properties or objects in the object, which is a sinkhole: (.
2. Using OData
Many people recommend that you include the. NET OData class Library in your project, using only its delta class to implement patch requests. This looks a little strange. OData is a completely different big guy than the neat JSON API. I bright odata a bit cumbersome, not intuitive, not elegant.
Also, it seems that some of the underlying types are updated with the OData class library in the JSON WEB API project. Because the OData class library is designed for data in OData format, this format is not as elegant as the JSON format. It seems that many people are using (or trying to use) OData to implement patch requests in JSON format, but they don't seem to be ideal.
3. Using a patch type with a nullable (nullable) property
Suppose we want to implement updating the PageCount property in the book object. In the book type, name is a required property, and the others like language are nullable. This workaround is to create a book patch type, where the PageCount, name, and other properties are set to be nullable. If the HTTP request provides a value for a property, the property is assigned a value. If no value is provided, this property is not changed. If you want to empty the value of this property, provide null in the request.
This doesn't seem so bad: (But when the nullable property in the passed data is null, you need to write extra logic in the patch type.) Also write the corresponding patch type for each type that needs a patch. Although it is not the best thing to create and modify a well-established type many times, maintenance will be a sinkhole.
This method is only used to set a property OK, if the property is an array, I want to add an item in it, then there is no way, unless the entire array is completely rewritten to support patch operations. or write an API for each location where you want to manipulate the array. Isn't there an elegant way?
What is JSON Patch
The often-mentioned OData doesn't really work, so why do I have to use OData to implement JSON-type patch operations? What is the most elegant way to achieve this? Is there no JSON patch standard?
It's a clang! This is the standard for JSON patches: RFC6902. The patch operation is interpreted with a directive such as "set field X to this value", so that one or more instructions can explain how to manipulate the object. It also supports a variety of other operations, such as adding and removing array elements from an object that needs to be patched, as well as setting properties for nested objects, and so on. ' Replace ', ' move ', ' Copy ' and ' test ' operations are all defined. Interestingly, the ' test ' method can check if a property is equal to the target value and should be useful.
The JSON patch looks like this:
{"foo":"bar"}
If we want to add a property named "Name" with a value of "Carly", then the HTTP Patch request body sent is as follows:
[ {"op":"add","path":"/name","vale":"Carly"}]
The response we may receive is as follows:
{ "foo":"bar", "name":"Carly"}
The JSON patch has its own MIME type: application/json-patch+json
.
It almost solves all the flaws in other methods and is more restful:o. The URI can also be consistent with the object, except that the instructions in the request contain the operational data, but the instruction is understood and very clear. We can clearly use various ways to manipulate properties, which can put a number of operations in a single request. Perfect!
A lot of people are still advocating the way the JSON patch was introduced before 2003, and some of the wrong comments misled many learners. Thank you very much, William Durant, and sharply's blog. Don ' t Patch like an Idiot "is this blog post that inspired me. I know that although it has not prompted JSON patches or XML patches to be supported by. NET native, they are not even mentioned in the. NET Web API's Guide. But this approach is undoubtedly the right and the best way.
How to use JSON patches in. NET Web API 2
Now that we know the right way to do it, how do you write the code? Refer to the JSON standard that Michael's post refers to in the first line of the JSON API. Although the main purpose of Michael's blog is to introduce his JSON patch library! But it's still worth learning.
Here is the essence of picking:
1. Nuget Installation:Install-Package JsonPatch -Version 1.0.0
1. Support MIME type and format
public static void CongigureApis(HttpConfiguration config){ config.Formatters.Add(new JsonPatchFormatter()); }
1. Implementing the Patch method in your API controller
public void Patch(Guid id, JsonPatchDocument<SomeDto> patchData){//Remember to do some validation, error handling, and all that fun stuffvar objectToUpdate = repository.GetById(id); patchData.ApplyUpdatesTo(objectToUpdate); repository.Save(objectToUpdate); }
执行patch请求的Http请求报文如下所示
PATCH /my/data HTTP/1.1Host: example.orgContent-Type: application/json-patch+json [ { "op": "add", "path": "/a/b/c", "value": "foo" }]
Development trend
It is worth noting that the JSON patch library has a little known issues and limitations. If you have used it in your project, if you have fixed its issues or added functionality, please contribute your code.
Using Michael's Jsonpatch library, there is a few scenarios that might come up. One is preventing patch of specific properties, which should being fairly easy to solve with a custom attribute added to the Data model.
(This passage has not been understood)
Recently, Asp.net5 seems to be supporting JSON patches.
Implementing a patch request with JSON in Web API 2