在web api团队创建的OData示例之后,我的控制器具有以下支持补丁:
public HttpResponseMessage Patch([FromODataUri] int key, Deltaitem) { var dbVersion = myDb.GetById(key); if(dbVersion == null) throw Request.EntityNotFound(); item.Patch(dbVersion); myDb.Update(dbVersion); return Request.CreateResponse(HttpStatusCode.NoContent); }
并使用自动生成的客户端(派生自DataServiceContext
),我提交了这样的补丁请求:
var foo = svcContainer.Foos.Where (f => f.Id == 1).SingleOrDefault(); foo.Description = "Updated Description"; svcContainer.UpdateObject(foo); svcContainer.SaveChanges(SaveChangesOptions.PatchOnUpdate);
但是,在fiddler中跟踪调用,我看到Foo的所有其他属性都被序列化并发送到服务.这是正确的行为吗?我希望只通过网络发送ID和描述.另外,如果我调试服务方法并调用
GetChangedPropertyNames
在item上,返回其所有属性名称.
我应该在客户端上创建某种Delta实例吗?
我理解服务的断开性质,因此服务端没有用于跟踪更改的上下文,但在我看来,api团队为某个原因添加了对补丁的支持,所以我想知道客户端是否应该以不同的方式调用更新.
YiDing提供的链接解释了如何从客户端创建一个真正的PATCH请求(使用Microsoft.OData.Client.DataServiceContext
由Microsoft.OData.Client 6.2.0
上面和上面创建的.为方便起见,这里是代码片段:
var svcContainer = new Default.Container(); var changeTracker = new DataServiceCollection (svcContainer.Foos.Where(f => f.Id == 1)); changeTracker[0].Description = "Patched Description"; svcContainer.SaveChanges();
该DataServiceCollection
工具财物跟踪,并使用这种模式,只有更新的属性发送到服务.不使用DataServiceCollection
和简单使用
svcContainer.UpdateObject(foo); svcContainer.SaveChanges();
所有属性仍然通过电线发送,尽管相反的文档,至少是 Microsoft.OData.Client 6.7.0
现在,Microsoft.OData.Client版本6.2.0支持客户端属性跟踪.它将仅检测实体的已修改属性,并将更新请求作为PATCH而不是PUT发送,以满足您的方案的要求.有关更多详细信息,请参阅此博客文章:http: //blogs.msdn.com/b/odatateam/archive/2014/04/10/client-property-tracking-for-patch.aspx