什么是做ServiceStack补丁部分更新推荐的方式? [英] What is the recommended way to do partial updates with PATCH in ServiceStack?

查看:208
本文介绍了什么是做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屋!

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