servicestack,Api,servicestack" /> servicestack,Api,servicestack" />

Api 建议使用ServiceStack中的修补程序进行部分更新的方法是什么?

Api 建议使用ServiceStack中的修补程序进行部分更新的方法是什么?,api,servicestack,Api,servicestack,我正在使用ServiceStack框架构建一个RESTful API。我需要更新的很多资源都非常大,每个类最多有40个属性,因此我想做部分更新而不是替换整个资源。客户机通常只需要更新40个属性中的一个或两个,所以我只想发送一个由几个属性组成的JSON正文 由于所有属性的组合都是可能的,因此不可能按照此处的建议对每个类进行“更新”类: 在Microsoft ASP.NET WebAPI OData包中,有一个Delta类,它接受一个类的子集并基于该子集更新资源()。这是我想要的功能,因为我将拥有相

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

由于所有属性的组合都是可能的,因此不可能按照此处的建议对每个类进行“更新”类:

在Microsoft ASP.NET WebAPI OData包中,有一个Delta类,它接受一个类的子集并基于该子集更新资源()。这是我想要的功能,因为我将拥有相当多的类,所以最好使用泛型方法

基本上,如果我有课的话

public class MyClass {
   public int a { get; set; }
   public int b { get; set; }
   ...
   public int z { get; set; }
}
我想用body的补丁请求更新MyClass的资源

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

有没有标准或推荐的方法可以通过ServiceStack实现这一点?

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

公共类MyClass{
公共int?a{get;set;}
公共int?b{get;set;}
公共int?c{get;set;}
//等等。
//当然,对象类型属性已经可以为空
公共字符串MyString{get;set;}
}
现在,如果客户机发送部分请求,如下所示:

{ "a": 1, "b": 0 }
检查DTO时,您将能够确定实际发送了哪些属性:

myClass.a == 1
myClass.b == 0
myClass.c == null
myClass.MyString == null
etc.
为DTO设置
补丁
路由,并在您的服务中实施
补丁
方法:

公共对象修补程序(MyClass请求)
{
var existing=GetMyClassObjectFromDatabase();
现有。使用非默认值填充(请求);
SaveToDatabase(现有);
...
}
populatewithnondefaultvalue
是这里的关键。它将把请求对象中的值复制到数据库实体上,但只复制不是默认值的属性。因此,如果一个值为null,它将不会复制它,因为客户端没有为它发送值。请注意,它将复制一个整数值0,因为我们将其设置为可为null的int,并且此方法将可为null的int的默认值视为null,而不是零。将DTO属性声明为可空不应该给代码的其余部分带来太多麻烦


请注意,这种方法很容易使用JSON。如果需要支持XML请求/响应,则可能需要使用
DataContract/DataMember
属性执行一些额外的工作,以确保正确处理空值。

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

公共类MyClass{
公共int?a{get;set;}
公共int?b{get;set;}
公共int?c{get;set;}
//等等。
//当然,对象类型属性已经可以为空
公共字符串MyString{get;set;}
}
现在,如果客户机发送部分请求,如下所示:

{ "a": 1, "b": 0 }
检查DTO时,您将能够确定实际发送了哪些属性:

myClass.a == 1
myClass.b == 0
myClass.c == null
myClass.MyString == null
etc.
为DTO设置
补丁
路由,并在您的服务中实施
补丁
方法:

公共对象修补程序(MyClass请求)
{
var existing=GetMyClassObjectFromDatabase();
现有。使用非默认值填充(请求);
SaveToDatabase(现有);
...
}
populatewithnondefaultvalue
是这里的关键。它将把请求对象中的值复制到数据库实体上,但只复制不是默认值的属性。因此,如果一个值为null,它将不会复制它,因为客户端没有为它发送值。请注意,它将复制一个整数值0,因为我们将其设置为可为null的int,并且此方法将可为null的int的默认值视为null,而不是零。将DTO属性声明为可空不应该给代码的其余部分带来太多麻烦


请注意,这种方法很容易使用JSON。如果需要支持XML请求/响应,您可能需要对
DataContract/DataMember
属性做一些额外的工作,以确保正确处理空值。

虽然esker的响应很好,但我想补充一点,这可能不足以处理空值字段,因为您不知道反序列化程序或用户是否创建了空值字段

一种方法是查看原始请求

另一种方法是要求用户提供额外的request(querystring)参数,以明确指定要修补的字段。 类似于:patch_fields=名称、描述、字段3
这种方法的好处是,最终用户可以更好地控制修补,并且不会错误地覆盖某个值(因为他使用了原始实体,忘记了清除某些字段)

虽然esker的响应很好,但我想补充一点,它可能不足以处理可空字段,因为您不知道反序列化程序或用户是否创建了该空字段

一种方法是查看原始请求

另一种方法是要求用户提供额外的request(querystring)参数,以明确指定要修补的字段。 类似于:patch_fields=名称、描述、字段3
这种方法的好处是,最终用户可以更好地控制修补,并且不会错误地重写某个值(因为他使用了原始实体,忘记了清除某些字段)

这种方法的问题是,如果您想实际清空某个值,即:{a':null,'b'='some value'}您可能想在DB中将该值实际设置为null,是吗?你可能会考虑这样的问题:这种方法的问题是,如果你想启动