Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/rest/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在Web API中更新集合?_C#_Rest_Asp.net Web Api_Url Routing_Asp.net Core Webapi - Fatal编程技术网

C# 如何在Web API中更新集合?

C# 如何在Web API中更新集合?,c#,rest,asp.net-web-api,url-routing,asp.net-core-webapi,C#,Rest,Asp.net Web Api,Url Routing,Asp.net Core Webapi,我有一个基本的Order-OrderItem情况,我正在努力在一个请求中更新项目(或者我是否应该?),让我解释一下,最后我会问这个问题 型号: public class Order { public int OrderId { get; set; } public string CustomerId { get; set; } public bool IsVoided { get; set; } public List<OrderItem> Item

我有一个基本的
Order
-
OrderItem
情况,我正在努力在一个请求中更新项目(或者我是否应该?),让我解释一下,最后我会问这个问题

型号:

public class Order
{
    public int OrderId { get; set; }
    public string CustomerId { get; set; }
    public bool IsVoided { get; set; }

    public List<OrderItem> Items { get; set; }
}

public class OrderItem
{
    public int OrderItemId { get; set; }
    public string Name { get; set; }
    public int Quantity { get; set; }
    public int Price { get; set; }
}
  • 更新
    Order
    的属性,如
    isvoid
    (但不是项目):
    [PATCH]/api/orders/{orderId}
  • 更新
    订单的项目(一次多个项目)
  • 这是我遇到的问题。。。我有一些想法:

    解决方案A:逐个更新订单的项目,因此端点:

    • [POST]/api/orders/{orderId}/items
      ,有效负载:
      {“数量”:25,“价格”:50}
    • [PUT]/api/orders/{orderId}/items/{itemId}
      ,有效负载:
      {“数量”:25,“价格”:50}
    • [DELETE]/api/orders/{orderId}/items/{itemId}
    优点:干净的架构。使用实体的端点添加/更新/删除实体

    缺点:如果用户更新500个项目并单击“保存”,则会向服务器发出500个请求。此外,它将接受部分成功

    解决方案B:通过使用有效负载更新订单:
    [PUT]/api/orders/{orderId}
    立即更新订单的项目:

    优点:性能,不允许部分成功

    缺点:如果用户更新50个项目,删除50个项目,并向订单中添加新的50个项目,在一个请求中(在
    订单
    实体上放置
    请求),我们将本质上在不同实体上添加、更新、删除50个项目-
    订单项目
    。我担心这是否是好的
    RESTful
    实践

    解决方案C:通过更新。。。集合:
    [PUT]/api/orders/{orderId}/items
    和有效负载:

    有效负载中的集合将完全替换系统中的集合,包括添加和删除操作

    优点:性能,部分成功是不允许的,你不会弄乱父实体

    缺点:对集合调用
    PUT
    请求是一种好的做法吗。通常,当您有
    PUT
    时,URI以某种ID结尾(您正在更新一个实体)。在本例中,URI将以“items”结尾。是这样做的吗

    解决方案D:另一种解决方案,可能带有
    补丁
    ?以前从未这样做过,但也许可以为
    订单
    实体发送
    补丁
    ,修补项目集合。在JsonDocument的值中,我会传递新项目的集合,要删除的项目和更新的项目


    那么,我的问题是:以下哪种解决方案最适合这种情况?A、 B、C或(如果存在)D?或者其他我没有想到的解决方案?

    如果您没有很多物品,那么解决方案A完全可以。它不适合您的情况,因为如果您有许多请求,它会使您的api变得健谈

    解决方案B一次发送很多信息。它遵循使用完整资源对象进行更新的实践,甚至还有一个http状态代码来表示部分成功。Response对象是一个考虑因素,让消费者知道成功的新URL,并指出失败的URL(如果有)以及原因。要么去,要么去

    解决方案C并没有那么安静。您并没有真正地更新任何单个资源,消费者很难理解

    解决方案D是B和C的合并。我希望在这里使用它,因为您并没有真正更新完整的对象。您可以使用与B相同的url

    扩展超文本传输协议(HTTP)的几个应用程序 需要一个功能来进行部分资源修改。现存的 HTTP PUT方法只允许完全替换文档。 该提案添加了一个新的HTTP方法PATCH,以修改现有的 HTTP资源。 –RFC 5789


    看起来解决方案B最适合您的需求,但它让您担心,因为在一个请求中发生了很多事情。如果每个部件(添加/删除项目等)在概念上都是一件事——订单的更新,我并不认为这是一个问题。解决方案B对我来说似乎是最好的解决方案。解决方案B对我来说似乎是最好的解决方案。如果你想,你也可以添加A,但在内部我可能会调用B。你想在一个事务中一次更新所有内容,所以发送50个请求对我来说是错误的。
    {
        "customerId": 805,
        "isVoided": "false",
        "items": [
            {
                "itemId": 112233,
                "quantity": 25,
                "price": 50
            },
            {
                "itemId": 445566,
                "quantity": 20,
                "price": 40
            }
        ]
    }
    
    [
      {
          "op": "replace",
          "path": "/IsVoided",
          "value": true
      }
    ]
    
    {
        "customerId": 805,
        "isVoided": "false",
        "items": [
            {
                "itemId": 112233,
                "quantity": 25,
                "price": 50
            },
            {
                "itemId": 445566,
                "quantity": 20,
                "price": 40
            }
        ]
    }
    
    [
        {
            "itemId": 112233,
            "quantity": 25,
            "price": 50
        },
        {
            "itemId": 445566,
            "quantity": 20,
            "price": 40
        }
    ]