zoukankan      html  css  js  c++  java
  • 在 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

  • 相关阅读:
    [UOJ UNR #2]积劳成疾
    [UOJ UNR#2 黎明前的巧克力]
    [UOJ UNR#2 UOJ拯救计划]
    [Codeforces Round #431]简要题解
    【UOJ UNR #1】争夺圣杯
    【UOJ UNR #1】火车管理
    [UOJ UNR#1]奇怪的线段树
    [暑假的bzoj刷水记录]
    项目(一)--python3--爬虫实战
    接收端--服务器详细阐述
  • 原文地址:https://www.cnblogs.com/jinzesudawei/p/12861769.html
Copyright © 2011-2022 走看看