在web api团队创建的OData示例之后,我的控制器具有以下支持补丁:
public HttpResponseMessage Patch([FromODataUri] int key, Delta<Foo> item)
{
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
,返回其所有属性名称。
我应该在客户端上创建某种Delta实例吗?
我理解服务的断开性质,因此服务端没有用于跟踪更改的上下文,但是在我看来,api团队因为某个原因添加了对补丁的支持,所以我我想知道客户端是否应该以不同的方式调用更新。
YiDing提供的链接说明了如何从客户端创建真正的PATCH请求(使用Microsoft.OData.Client.DataServiceContext
及以上创建的Microsoft.OData.Client 6.2.0
。
为方便起见,以下是代码段:
var svcContainer = new Default.Container(<svcUri>);
var changeTracker = new DataServiceCollection<Foo>(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
开始
答案 0 :(得分:5)
现在,Microsoft.OData.Client版本6.2.0支持客户端属性跟踪。它将仅检测实体的已修改属性,并将更新请求作为PATCH而不是PUT发送,以满足您的方案的要求。有关更多详细信息,请参阅此博客文章: http://blogs.msdn.com/b/odatateam/archive/2014/04/10/client-property-tracking-for-patch.aspx