.Net Core Web Api_笔记08_HTTP资源操作模式PATCH

在HTTP请求中 PUT 跟 PATCH 都代表更新
然後他们之间比较主要的差异在於

PUT 用在更新整个资源(full resource updates)
比较有点类似整个覆盖、覆写 (比如:整个Student的Entity都取代)
PATCH 用在更新部份资源(partial resource updates)
比较有点像书柜里的书拿出来改放其他本 (比如:只更改Student中的name属性)

Patch请求
别於POST、PUT使用的ContentType:"application/json"建议使用
的ContentType是 "application/json-patch+json",此外也无法透过form-data方式来做提交。

对HttpPatch操作预设我们的.net core web api专案需要
先安装Json.NET服务注入的.net core 套件
名称: Microsoft.AspNetCore.Mvc.NewtonsoftJson

Install-Package Microsoft.AspNetCore.Mvc.NewtonsoftJson

https://ithelp.ithome.com.tw/upload/images/20210908/20107452aSf5F4dEun.png

安装好後於Startup.cs当中的ConfigureServices 方法

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers().AddNewtonsoftJson();
}

我们来注入要使用的服务
这里 Microsoft.AspNetCore.Mvc.NewtonsoftJson 里面要注册的服务
主要是和
.AddControllers()
.AddControllersWithViews()
.AddRazorPages()
兼容
需透过Builder Design Pattern的风格一层一层添加

在TeacherController.cs中扩充 HttpPatch的Action Method
public string UpdatePart(JsonPatchDocument jsonPatchDocument)....

这里由於设计上要传入的资料要依赖Microsoft.AspNetCore.JsonPatch套件
因此补去nuget安装
并引入命名空间
using Microsoft.AspNetCore.JsonPatch;

https://ithelp.ithome.com.tw/upload/images/20210908/20107452TChE9CFIMJ.png

TeacherController.cs

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.JsonPatch;
using Microsoft.AspNetCore.Mvc;
using MyApiTest1.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace MyApiTest1.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class TeacherController : ControllerBase
    {
        [HttpPost("Add")]
        public string AddPerson(Person person)
        {
            int id = person.Id;
            string name = person.Name;
            int age = person.Age;
            string sex = person.Sex;
            return "完成添加";
        }

        [HttpPut("Update")]
        public string UpdatePerson(Person person)
        {
            int id = person.Id;
            string name = person.Name;
            int age = person.Age;
            string sex = person.Sex;
            return "完成更新";
        }


        [HttpDelete("Delete")]
        public string DeletePerson(string id)
        {
            string msg = "";
            if (!string.IsNullOrEmpty(id))
            {
                var strId = id;
                //删除作业.....

                //删除作业.....
                msg = "完成删除";
            }
            return msg;
        }

        [HttpHead("head")]
        public void HeaderMessage()
        {
            //return "test 123";//用HttpHead不会回传此内容
        }

        [HttpOptions("check")]
        public string CheckServer()
        {
            return "from Server message";
        }

        [HttpPatch("part")]
        public string UpdatePart(JsonPatchDocument<Person> jsonPatchDocument)
        {
            //得到资料後进行部分更新
            //....
            return "完成部分更新";
        }

    }
}

前端一样我们准备好一个新的html并用jQuery模拟呼叫方式

UpdatePartTeacher.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Update Part Teacher Info</title>
    <script src="jquery/jquery.min.js"></script>
</head>
<body>
    <div>
        <input type="button" id="btnUpdatePart" value="部分更新" />
        <span id="msg"></span>
    </div>

    <script type="text/javascript">
        $("#btnUpdatePart").click(function () {
            $.ajax({
                //请求模式
                type: "patch",
                //请求的URL
                url: "api/Teacher/part",
                //预期server responde的资料型态
                dataType: "text",
                //请求送出发送的资料(body内文json字串)
                data: JSON.stringify([{ op: "replace", path: '/name', value:'Sandy' }]),
                //内文型态
                contentType: "application/json-patch+json",
                success: function (result) {
                    $("#msg").html(result);
                }
            });
        });
    </script>
</body>
</html>

运行测试
https://ithelp.ithome.com.tw/upload/images/20210908/20107452lUdcCJ6qQ1.png

若要更新的不只一属性则直接在json传入的中括号[...]中额外逗号分隔去新增{....}即可
[ {属性1} , {属性2} .....]

这里传送到server-side的json格式参数
有固定的格式

op代表操作Operations种类
https://docs.microsoft.com/zh-tw/aspnet/core/web-api/jsonpatch?view=aspnetcore-5.0#operations

https://ithelp.ithome.com.tw/upload/images/20210908/20107452WrqRzYDZ85.png

path 这里代表的是单一个属性name
就用 /属性名称 来表示

若针对的属性为一集合型别则
/属性名称/索引号

若属性是另一个class
然後是class在下一层级的属性则可这样写
/class型别的属性/属性

比方
/address/zipCode

以上就是所有HTTP资源操作的种类分享
目前都没有搭配资料库实作所以可能还没有感觉
之後再慢慢实作搭配DB後的运作方式

本篇同步发表至个人部落格
https://coolmandiary.blogspot.com/2021/09/net-core-web-api08httppatch.html

Ref:
How to perform partial resource updates with JSON Patch and ASP.NET Core
https://benfoster.io/blog/aspnet-core-json-patch-partial-api-updates/

ASP.NET Core Web API 中的 JsonPatch
https://docs.microsoft.com/zh-tw/aspnet/core/web-api/jsonpatch?view=aspnetcore-5.0

JavaScript Object Notation (JSON) Patch
https://datatracker.ietf.org/doc/html/rfc6902

Using HttpClient to Send HTTP PATCH Requests in ASP.NET Core
https://code-maze.com/using-httpclient-to-send-http-patch-requests-in-asp-net-core/

https://www.yogihosting.com/aspnet-core-api-controllers/


<<:  [Tableau Public] day 8:尝试制作第一张视觉仪表板

>>:  [Day08] Dependency Injection Part2 - 依赖介面

【从零开始的Swift开发心路历程-Day27】如何在App中播放影片!

今天来教大家要怎麽在App上播放Youtube影片! 我们要用的是WebKitView来达成这个功能...

我想推荐的WordPress主题,2020黑色星期五折扣开跑

在我的架站经验中,我始终在「想要的功能与样式」和「网页载入速度」中不断拉扯! 不过,这样也好,促使我...

Day27 interrupt 的处理程序

前言 昨天讲完了上半部的考量之後,可以知道上半部就是要追求快速,能尽快把事情处理好交给下半部就是上半...

[Day 30] 最後一天了,来复习看看我们学了些什麽

今天是铁人赛的最後一天了,我们花点时间来看看这三十天我们都介绍了些什麽。 首先,我们介绍了一下 Ko...

用ffprobe列出mp4 关键帧的时间

列出所有的关键帧时间 ffprobe.exe -v error -select_streams v:...