What is the correct way to invoke a patch from an OData client in Web Api 2

Following the OData samples created by the web api command, my controller has the following to support the fix:

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); } 

and using the automatically generated client (obtained from the DataServiceContext ), I send a patch request as follows:

 var foo = svcContainer.Foos.Where (f => f.Id == 1).SingleOrDefault(); foo.Description = "Updated Description"; svcContainer.UpdateObject(foo); svcContainer.SaveChanges(SaveChangesOptions.PatchOnUpdate); 

However, by tracking the call in fiddler, I see that all other Foo properties are serialized and sent to the service. Is this the right behavior? I expected that only the identifier and description will be sent to the wire. Also, if I debug the service method and call

GetChangedPropertyNames on an element, all its property names are returned.

Should I create some kind of Delta instance on the client?

I understand the unrelated nature of the service, and therefore the service side has no context for tracking changes, but it seems to me that the api team added support for the patch for some reason, so I'd like to know if the client should refer to the update in another way.

Update

The YiDing link provided explains how to create a true PATCH request from a client (using Microsoft.OData.Client.DataServiceContext created by Microsoft.OData.Client 6.2.0 and later. For convenience, here is a code snippet:

 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 implements property tracking, and using this template only updated properties are sent to the service. Without using a DataServiceCollection and just using

 svcContainer.UpdateObject(foo); svcContainer.SaveChanges(); 

all properties are still sent over the cable, despite the documentation to the contrary, at least Microsoft.OData.Client 6.7.0

+6
source share
1 answer

Client side property tracking is now supported with Microsoft.OData.Client version 6.2.0. It will only detect the changed properties of the object and send the update request as PATCH instead of PUT to match the requirements of your script. Please refer to this blog post for more information: http://blogs.msdn.com/b/odatateam/archive/2014/04/10/client-property-tracking-for-patch.aspx

+4
source

All Articles