在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
安裝好後於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;
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>
運行測試
若要更新的不只一屬性則直接在json傳入的中括號[...]中額外逗號分隔去新增{....}即可
[ {屬性1} , {屬性2} .....]
這裡傳送到server-side的json格式參數
有固定的格式
op代表操作Operations種類
https://docs.microsoft.com/zh-tw/aspnet/core/web-api/jsonpatch?view=aspnetcore-5.0#operations
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/