简体   繁体   English

使用 Simple.OData.Client 仅更新某些属性

[英]Update only certain properties with Simple.OData.Client

I'm using Simple.OData.Client and I would like to update certain properties of an entity.我正在使用 Simple.OData.Client 并且我想更新实体的某些属性。

Let's say I have following class in C#:假设我在 C# 中有以下课程:

[DataContract(Name = "entity")]
public class MyEntity
{
        [DataMember(Name = "propertyA")]
        public string MyPropertyA { get; set; }

        [DataMember(Name = "propertyB")]
        public string MyPropertyB { get; set; }
}

I'm trying to update propertyA like this:我正在尝试像这样更新 propertyA:

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

I took this as an example: https://github.com/object/Simple.OData.Client/wiki/Updating-entries我以此为例: https : //github.com/object/Simple.OData.Client/wiki/Updating-entries

My problem is that sends a PUT request with propertyA=test but also propertyB=null.我的问题是发送一个带有 propertyA=test 但 propertyB=null 的 PUT 请求。 It tries to set null value for the property I don't want to change.它尝试为我不想更改的属性设置空值。

Is it possible to only update certain properties and to send HTTP PATCH in the OData request?是否可以仅更新某些属性并在 OData 请求中发送 HTTP PATCH?

You should use PATCH instead of PUT.您应该使用 PATCH 而不是 PUT。

The HTTP Standard says: HTTP 标准说:

A successful PUT of a given representation would suggest that a subsequent GET on that same target resource will result in an equivalent representation being sent in a 200 (OK) response.给定表示的成功 PUT 将表明对同一目标资源的后续 GET 将导致在 200 (OK) 响应中发送等效表示。

So if you issue a PUT with just MyPropertyA in the request then a subsequent GET should return an Entity with MyPropertyB as null .因此,如果您在请求中发出一个仅包含MyPropertyA的 PUT,那么后续的 GET 应该返回一个带有MyPropertyB的实体为null

Primarily, the OData v4 Standard says: OData v4 标准主要说:

Services that support PUT MUST replace all values of structural properties with those specified in the request body.支持 PUT 的服务必须用请求正文中指定的值替换结构属性的所有值。 Missing non-key, updatable structural properties not defined as dependent properties within a referential constraint MUST be set to their default values .缺少未定义为引用约束内的依赖属性的非关键、可更新结构属性必须设置为其默认值

While you may be able to get the client to not send MyPropertyB , a proper OData server MUST interpret that as a request to set the value to be default (null).虽然您可以让客户端不发送MyPropertyB ,但适当的 OData 服务器必须将其解释为将值设置为默认值(null) 的请求。

You should use an anonymous object for doing that or find some way to configure the client's serializer to ignore default values (eg null on a ref type).您应该使用匿名对象来执行此操作,或者找到某种方法来配置客户端的序列化程序以忽略默认值(例如,引用类型为 null)。

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

You can achieve this with the typed fluent API.您可以使用类型化的 fluent API 来实现这一点。

You have to select the fields explicitly for reads (.Select) and set them explicitly on writes.(.Set) to prevent the whole structure being sent.您必须为读取 (.Select) 显式选择字段,并在写入时显式设置它们。 (.Set) 以防止发送整个结构。

I think you are almost there.. Instead of .Set(new MyEntity use .Set(new .我想你快到了.. 而不是.Set(new MyEntity use .Set(new .

I also use a populated entity instance and simplified .Set我还使用填充的实体实例和简化的 .Set

              .Set(new 
              {
                myEntity.MyPropertyA,
              })

is equivalent to相当于

              .Set(new 
              {
                MyPropertyA = myEntity.MyPropertyA,
              })

All up then this should work.一切都那么这应该工作。 Unless the DataContract is somehow causing an issue.除非 DataContract 以某种方式导致问题。 In my working example there isn't DataContract attributes for the class.在我的工作示例中,该类没有 DataContract 属性。 Verified with Fiddler that only specified fields are sent ( in my code ).使用 Fiddler 验证仅发送指定的字段(在我的代码中)。

 var myEntity = new MyEntity() 
 {
    MyPropertyA = "test"
 };

 await _simpleOdataClient.For<MyEntity>()
              .Key(key)
              .Set(new 
              {
                myEntity.MyPropertyA,
              })
              .UpdateEntryAsync();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM