在 Blazor Wasm 中調用 HttpPatch 失敗之解決,加深理解 PATCH 及其非冪等性邏輯


背景

在 Blazor Wasm 應用中,嘗試使用 HttpPatch 對記錄進行更新操作。

[Route("api/[controller]")]
[ApiController]
public class PersonController : ControllerBase
{
    private List<PersonDataModel> _personList = new List<PersonDataModel>
    {
        new PersonDataModel { Id = 1, FirstName = "三兒", LastName = "" },
        new PersonDataModel { Id = 2, FirstName = "四兒", LastName = "" }
    };

    [HttpPatch("{id}")] public PersonDataModel Patch(int id, [FromBody]JsonPatchDocument<PersonDataModel> patch)
    {
        if (patch == null) return null;

        var personItem = _personList.FirstOrDefault(t => t.Id == id);
        if (personItem == null) return null;

        patch.ApplyTo(personItem); return personItem;
    }
}

錯誤信息

{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
    "title": "One or more validation errors occurred.",
    "status": 400,
    "traceId": "|7551fbb9-4a1e3fd4cf6fdd94.",
    "errors": {
        "$": [
            "The JSON value could not be converted to Microsoft.AspNetCore.JsonPatch.JsonPatchDocument`1[Demo_Blazor_Wasm.Shared.PersonDataModel]. Path: $ | LineNumber: 0 | BytePositionInLine: 1."
        ]
    }
}

解決方案

https://stackoverflow.com/a/58557161/13501202

1. Add a package reference to Microsoft.AspNetCore.Mvc.NewtonsoftJson.
2. Change code in the startup to services.AddControllersWithViews().AddNewtonsoftJson();

測試,執行成功

關於 HttpPatch 及其 非冪等性

1. 在討論 RESTful API 接口設計時,會提到兩個基本的特性:"安全性"和"冪等性"。

https://juejin.im/post/5ea14e55f265da47c15cd8d1

安全性 是指調用接口不對資源產生修改。
冪等性 是指調用方法1次或N次對資源產生的影響結果都是相同的。
需要特別注意的是:這里冪等性指的是對資源產生的影響結果,而不是調用HTTP方法的返回結果。

從上述表格中可以看出,HTTP 方法的冪等性和安全性並不是同一個概念:

  • OPTONS、HEAD、GET 既是冪等也是安全的,不修改資源,多次調用對資源的影響是相同的。
  • POST、PATCH 既不冪等也不安全,修改了資源,同時多次調用時,對資源影響是不同的。
  • PATCH 的影響不同在於,每次的局部更新可能會導致資源不一樣。
  • PUT 是對資源的全量更新,多次更新總是對資源影響是一致的,所以它是冪等,但不安全。
  • DELETE 用於刪除資源,多次調用的情況下,都是刪除了資源,所以它是冪等,但不安全。

2. PATCH可以進行哪些操作?

https://www.cnblogs.com/lwqlun/p/10433615.html

JSON Patch 是一種使用API顯式更新文檔的方法。
它本身是一種契約,用於描述如何修改文檔(例如:將字段的值替換成另外一個值),而不必同時發送其他未更改的屬性值。
你可以在以下鏈接(http://jsonpatch.com/)中找到JSON Patch的官方文檔。

所有的JSON Patch請求都是遵循一個相似的結構。它有一個固定的"操作"列表。
每個操作本身擁有3個屬性:

  • "op" - 定義了你要執行何種操作,包括 add, remove, replace, copy, move, test 等。
  • "path" - 定義了你要操作對象屬性路徑。用前面的Person類為例,如果你希望修改FirstName屬性,那么你使用的操作路徑應該是"/FirstName"。
  • "value" - 在大部分情況下,這個屬性表示你希望在操作中使用的值。

3. 如何理解 PATCH 是非冪等的?

當 "op" = "replace" 時,正常情況下其結果是冪等的。
當 "op" = "add" 時,下面這個栗子是非冪等的。

 

參考資料

如何在ASP.NET Core中使用JSON Patch
https://www.cnblogs.com/lwqlun/p/10433615.html

理解RESTful API 架構設計規范與實踐
https://juejin.im/post/5ea14e55f265da47c15cd8d1

Put vs Patch Api in .Net Core
https://www.williamleme.com/posts/put-vs-patch-api-net-core/

為什么 HTTP PATCH 方法不是冪等的及其延伸
https://juejin.im/post/5ca83c6351882544183367e2


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM