Search code examples
c#-4.0odata

Restricting properties sent in a ODATA4 update


When I am trying to update the a property (AvaliableQuantity) on an object and then update it via ODATA (using the oData v4 Client Code Generator). The problem is when I send the request (Fiddler output below) I get an error saying that "Only AvailableQuantity may be updated." Is there a way of specifying which of the properties can be updated (maybe via attributes?)

PATCH https://*****************/v1/DCQuantities(ProductID=33578709,DistributionCenterID=17) HTTP/1.1
OData-Version: 4.0
OData-MaxVersion: 4.0
Content-Type: application/json;odata.metadata=minimal
Accept: application/json;odata.metadata=minimal
Accept-Charset: UTF-8
User-Agent: Microsoft ADO.NET Data Services
Authorization: Bearer ************************
Host: **************
Content-Length: 153
Expect: 100-continue
{"@odata.type":"#ChannelAdvisor.RestApi.V1.Models.DCQuantity","AvailableQuantity":30,"DistributionCenterID":17,"ProductID":33578709,"ProfileID":22001149}

Below is the raw response from Fiddler

HTTP/1.1 400 Bad Request
Content-Length: 88
Content-Type: application/json; odata.metadata=minimal; charset=utf-8
Server: Microsoft-IIS/7.5
OData-Version: 4.0
X-ServerName: **********
Date: Wed, 16 Dec 2015 15:50:52 GMT

{
  "error":{
    "code":"","message":"Only AvailableQuantity may be updated."
  }
}

I have been able to update properties on other objects so I know that the authentication (OAUTH2) and the basic classes are working.

Does anybody have any ideas on what I could try please?

Many thanks

Jonathan


Solution

  • OK, I have realised what I was doing wrong from this post (http://blogs.msdn.com/b/odatateam/archive/2014/04/10/client-property-tracking-for-patch.aspx). I was using code like this to get the object before changing it:

    var product = target.Products.Expand("DCQuantities").Where(p => p.Sku == "JRSTEST1").First();
    product.First().DCQuantities[0].AvailableQuantity = 42;
    target.UpdateObject(product.DCQuantities[0]); 
    var result = target.SaveChanges();
    

    What I needed to do was assign the result of the query to a DataServiceCollection<>() class which would then look after tracking what was actually changed and manage the whole update for me.

    var product = new DataServiceCollection<Product>(target.Products.Expand("DCQuantities").Where(p => p.Sku == "JRSTEST1"));
    product.First().DCQuantities[0].AvailableQuantity = 42;
    var result = target.SaveChanges();