在 ServiceStack 中使用 PATCH 进行部分更新的推荐方法是什么? [英] What is the recommended way to do partial updates with PATCH in ServiceStack?

查看:27
本文介绍了在 ServiceStack 中使用 PATCH 进行部分更新的推荐方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 ServiceStack 框架构建一个 RESTful API.我需要更新的很多资源都非常大,每个类最多有 40 个属性,所以我想做部分更新,而不是替换整个资源.通常客户端只需要更新 40 个属性中的一两个,所以我只想发送一个由少数属性组成的 JSON 正文.

I am building a RESTful API using the ServiceStack framework. A lot of the resources that I need to update are quite big, with up to 40 attributes per class, so I would like to do partial updates instead of replacing the entire resource. Often the client will only need to update one or two attributes out of the 40, so I would like to just send a JSON body consisting of the few attributes.

由于所有属性组合都是可能的,因此按照此处的建议为每个类创建一个更新"类是不可行的:https://github.com/ServiceStack/ServiceStack/wiki/New-Api#patch-request-example

Since all combinations of attributes are possible, it is not feasible to make an "Update" class per class as suggested here: https://github.com/ServiceStack/ServiceStack/wiki/New-Api#patch-request-example

在 Microsoft ASP.NET WebAPI OData 包中有一个 Delta 类,它采用类的一个子集并基于该子集更新资源 (http://www.strathweb.com/2013/01/easy-asp-net-web-api-resource-updates-with-delta/).这是我想要的功能,因为我将拥有相当多的类,因此最好使用通用方法.

In the Microsoft ASP.NET WebAPI OData package there is a Delta class that takes a subset of a class and updates the resource based on this subset (http://www.strathweb.com/2013/01/easy-asp-net-web-api-resource-updates-with-delta/). This is the functionality I would like to have, as I will be having quite a few classes so a generic method would be best.

基本上,如果我有课

public class MyClass {
   public int a { get; set; }
   public int b { get; set; }
   ...
   public int z { get; set; }
}

我想使用带有正文的 PATCH 请求更新 MyClass 的资源

I would like to update a resource of MyClass with a PATCH request with body

{"a":42,"c":42}

是否有使用 ServiceStack 实现此目的的标准或推荐方法?

Is there a standard or recommended way to accomplish this with ServiceStack?

推荐答案

将 DTO 中的任何标量值声明为可为空.这将允许您确定请求中实际发送了哪些字段:

Declare any scalar values in your DTO as nullable. This will allow you to determine which fields were actually sent in the request:

public class MyClass {
    public int? a { get; set; }
    public int? b { get; set; }
    public int? c { get; set; }
    // etc.
    // object-type properties are already nullable of course
    public string MyString { get; set; }
}

现在,如果客户端发送部分请求,如下所示:

Now if a client sends a partial request, like so:

{ "a": 1, "b": 0 }

在检查 DTO 时,您将能够确定实际发送了哪些属性:

You'll be able to determine which properties were actually sent when inspecting your DTO:

myClass.a == 1
myClass.b == 0
myClass.c == null
myClass.MyString == null
etc.

为您的 DTO 设置一个 PATCH 路由并在您的服务中实现一个 Patch 方法:

Set up a PATCH route for your DTO and implement a Patch method in your service:

public object Patch(MyClass request)
{
    var existing = GetMyClassObjectFromDatabase();
    existing.PopulateWithNonDefaultValues(request);
    SaveToDatabase(existing);
    ...
}

PopulateWithNonDefaultValues 是这里的关键.它会将值从您的请求对象复制到数据库实体上,但只会复制不是默认值的属性.因此,如果一个值为空,它不会复制它,因为客户端没有为它发送一个值.请注意,它会复制一个为零的整数值,因为我们将其设为可空 int,并且此方法认为可空 int 的默认值是 null,而不是零.将您的 DTO 属性声明为可为空不会给您的其余代码带来太多麻烦.

PopulateWithNonDefaultValues is key here. It will copy values from your request object onto the database entity, but will only copy properties that are not the default values. Thus, if a value is null, it won't copy it, because the client didn't send a value for it. Notice that it will copy an integer value of zero though, because we made it a nullable int, and the default value for a nullable int is considered by this method to be null, not zero. Declaring your DTO properties as nullable shouldn't cause much of a hassle in the rest of your code.

请注意,此方法适用于 JSON.如果您需要支持 XML 请求/响应,您可能需要对 DataContract/DataMember 属性做一些额外的工作,以确保正确处理空值.

Note that this approach works easily with JSON. If you need to support XML requests/responses, you may need need to do some additional work with DataContract/DataMember attributes to insure that nulls are handled correctly.

这篇关于在 ServiceStack 中使用 PATCH 进行部分更新的推荐方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆