HttpClient partial update

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"]
}

Json Patch详情

实现

客户端

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));
        }
posted @ 2020-04-28 15:46  青玄鸟  阅读(144)  评论(0编辑  收藏  举报