1

我正在使用 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; }
}

我正在尝试像这样更新 propertyA:

await _simpleOdataClient.For<MyEntity>()
                  .Key(key)
                  .Set(new MyEntity
                  {
                    MyPropertyA = "test"
                  })
                  .UpdateEntryAsync();

我以此为例:https ://github.com/object/Simple.OData.Client/wiki/Updating-entries

我的问题是发送一个带有propertyA = test 但propertyB = null 的PUT 请求。它尝试为我不想更改的属性设置空值。

是否可以只更新某些属性并在 OData 请求中发送 HTTP PATCH?

4

3 回答 3

1

您应该使用 PATCH 而不是 PUT。

HTTP 标准说:

给定表示的成功 PUT 将表明对同一目标资源的后续 GET 将导致在 200(OK)响应中发送等效表示。

因此,如果您仅MyPropertyA在请求中发出 PUT,则后续 GET 应返回带有MyPropertyBas的实体null

首先,OData v4 标准说:

支持 PUT 的服务必须将结构属性的所有值替换为请求正文中指定的值。缺失的非键、可更新结构属性未定义为引用约束中的依赖属性必须设置为其默认值

虽然您可以让客户端不发送MyPropertyB,但适当的 OData 服务器必须将其解释为将值设置为默认值(null) 的请求。

于 2021-07-25T16:24:15.877 回答
0

您可以使用类型化的 fluent API 来实现这一点。

您必须为读取明确选择字段(.Select)并在写入时明确设置它们。(.Set)以防止发送整个结构。

我想你快到了.. 而不是.Set(new MyEntity使用.Set(new .

我还使用了一个填充的实体实例并简化了 .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();
于 2019-10-14T06:49:24.063 回答
0

您应该使用匿名对象来执行此操作,或者找到某种方法来配置客户端的序列化程序以忽略默认值(例如,引用类型为 null)。

await _simpleOdataClient.For<MyEntity>()
                  .Key(key)
                  .Set(new
                  {
                    MyPropertyA = "test"
                  })
                  .UpdateEntryAsync();
于 2018-11-29T09:48:00.740 回答