我正在使用Simple.OData.Client,我想更新实体的某些属性。
假设我在C#中有以下课程:
[DataContract(Name = "entity")]
public class MyEntity
{
[DataMember(Name = "propertyA")]
public string MyPropertyA { get; set; }
[DataMember(Name = "propertyB")]
public string MyPropertyB { get; set; }
}
我正在尝试更新属性,如下所示:
await _simpleOdataClient.For<MyEntity>()
.Key(key)
.Set(new MyEntity
{
MyPropertyA = "test"
})
.UpdateEntryAsync();
我举了一个例子:https://github.com/object/Simple.OData.Client/wiki/Updating-entries
我的问题是发送一个属性a=test但属性B=null的PUT请求。它试图为我不想更改的属性设置null值。
是否可以只更新某些属性并在OData请求中发送HTTP PATCH?
您应该使用PATCH而不是PUT。
HTTP标准说:
给定表示的成功PUT表明,在同一目标资源上的后续GET将导致在200(OK(响应中发送等效表示。
因此,如果在请求中只发出MyPropertyA
的PUT,那么随后的GET应该返回MyPropertyB
作为null
的Entity。
OData v4标准主要规定:
支持PUT的服务必须将结构属性的所有值替换为请求体中指定的值。在引用约束中未定义为依赖属性的缺少非键、可更新的结构属性必须设置为其默认值。
虽然您可以让客户端不发送MyPropertyB
,但适当的OData服务器必须将其解释为将值设置为默认(null(的请求。
您应该使用匿名对象来执行此操作,或者找到一些方法来配置客户端的序列化程序以忽略默认值(例如,ref类型上的null(。
await _simpleOdataClient.For<MyEntity>()
.Key(key)
.Set(new
{
MyPropertyA = "test"
})
.UpdateEntryAsync();
您可以通过类型化的fluent API实现这一点。
您必须显式选择要读取的字段(.select(,并在写入时显式设置它们。(.Set(以防止发送整个结构。
我想你差不多到了。。使用.Set(新的MyEntity(而不是.Set(新的.
我还使用了一个填充的实体实例并进行了简化。设置
.Set(new
{
myEntity.MyPropertyA,
})
相当于
.Set(new
{
MyPropertyA = myEntity.MyPropertyA,
})
一切都好了,这应该行得通。除非DataContract以某种方式导致了问题。在我的工作示例中,该类没有DataContract属性。通过Fiddler验证,只发送指定的字段(在我的代码中(。
var myEntity = new MyEntity()
{
MyPropertyA = "test"
};
await _simpleOdataClient.For<MyEntity>()
.Key(key)
.Set(new
{
myEntity.MyPropertyA,
})
.UpdateEntryAsync();