full update 与 partial update
partial update:发送需要对远程资源做的变更(集合)
full update:发送变更后的资源实体
Json Patch
Json Patch 是描述一个json文档的变化的一种格式。可以避免在文档的一部分发生变化时发送整个文档。Json Patch在结合Http Patch Method 使用时,允许部分更新Api资源。Json Patch文档用Json格式表示:
原始文档:
{
"baz": "qux",
"foo": "bar"
}
Json Path:
[
{ "op": "replace", "path": "/baz", "value": "boo" },
{ "op": "add", "path": "/hello", "value": ["world"] },
{ "op": "remove", "path": "/foo" }
]
更新后文档:
{
"baz": "boo",
"hello": ["world"]
}
实现
客户端
private async Task PatchResource(HttpClient httpClient)
{
var patchDoc = new JsonPatchDocument<DemoForUpdate>();
patchDoc.Replace(d=>d.Title,"another title");
patchDoc.Remove(d=>d.Description);
var serializedChangeSet = JsonConvert.SerializeObject(patchDoc);
var request = new HttpRequestMessage(HttpMethod.Patch, "api/demos/163");
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
request.Content = new StringContent(serializedChangeSet);
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var response = await httpClient.SendAsync(request);
response.EnsureSuccessStatusCode();
var content =await response.Content.ReadAsStringAsync();
var updateDemo = JsonConvert.DeserializeObject<Demo>(content);
}
服务端
[HttpPatch("{demoId}")]
public async Task<IActionResult> PartiallyUpdateMovie(int demoId,
[FromBody] JsonPatchDocument<Models.DemoForUpdate> patchDoc)
{
var demoEntity = await _demosRepository.GetDemoAsync(demoId);
if (demoEntity == null)
{
return NotFound();
}
var demoToPatch = Mapper.Map<Models.DemoForUpdate>(demoEntity );
patchDoc.ApplyTo(demoToPatch, ModelState);
if (!ModelState.IsValid)
{
return new UnprocessableEntityObjectResult(ModelState);
}
Mapper.Map(demoToPatch, demoEntity );
_demosRepository.UpdateMovie(demoEntity);
await _demosRepository.SaveChangesAsync();
return Ok(_mapper.Map<Models.Demo>(demoEntity));
}