什么是做ServiceStack补丁部分更新推荐的方式? [英] What is the recommended way to do partial updates with PATCH in ServiceStack?
问题描述
我建立使用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
在微软ASP.NET的WebAPI的OData包有一个三角洲类,它的类的子集,并更新基于此子集资源(的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.
基本上,如果我有一个类
Basically, if I have a class
public class MyClass {
public int a { get; set; }
public int b { get; set; }
...
public int z { get; set; }
}
我想更新的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.
设置 PATCH
路线为您的DTO和服务实施补丁
方法:
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
这里是关键。它会从你的请求对象中的值复制到数据库实体,而只会复制不属于默认值的属性。因此,如果一个值为null,它不会复制,因为客户端没有为它发送的值。请注意,这将复制的零整数值,但因为我们做它一个可空int和可空INT的默认值是通过这种方法被认为是空,而不是0。声明你的DTO属性为空的应该不会造成太大的麻烦,在code的其余部分。
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 /数据成员
属性,以确保空的正确处理。
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补丁部分更新推荐的方式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!