在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/
<<: [Tableau Public] day 8:尝试制作第一张视觉仪表板
>>: [Day08] Dependency Injection Part2 - 依赖介面
今天来教大家要怎麽在App上播放Youtube影片! 我们要用的是WebKitView来达成这个功能...
在我的架站经验中,我始终在「想要的功能与样式」和「网页载入速度」中不断拉扯! 不过,这样也好,促使我...
前言 昨天讲完了上半部的考量之後,可以知道上半部就是要追求快速,能尽快把事情处理好交给下半部就是上半...
今天是铁人赛的最後一天了,我们花点时间来看看这三十天我们都介绍了些什麽。 首先,我们介绍了一下 Ko...
列出所有的关键帧时间 ffprobe.exe -v error -select_streams v:...