How to update an OData object and change its navigation properties in a single query?

I am trying to implement what, in my opinion, was a simple script using the OData service provided by the WCF data services (using the OData V3 application / json application; odata = verbose.) I can use the JSON Light format in the future). The main scenario is as follows:

I have two objects:

class Person { public int ID { get; set; } public string Name { get; set; } public virtual PersonCategory Category { get; set; } } class PersonCategory { public int ID { get; set; } public string Description { get; set; } public virtual ICollection<Person> People { get; set; } } 

Now I want to create a simple editing page for Person. This edit page can have an input for the name, as well as an input or a drop-down list for the Person category.

So the script:

  • Code loads Person using $ expand for the category: GET / api.svc / People (1)? $ expand = Category
  • The user edits the name of the person and his category.
  • The code for the page makes one request to update the properties of the name and category of Person.

The key here is in the "single request". This is the part with which it is difficult for me to find the documentation. I saw examples where they split number 3 above into two queries. Something like this (I don't remember the exact format - I'm also not sure if you need to DELETE the category link before doing the PUT):

 PATCH /api.svc/People(1) with content: {"Name": "new name" } PUT /api.svc/People(1)/$links/Category with content: { "url": "/api.svc/Categories(2)" } 

But I also heard him say, but did not demonstrate that it is possible to implement this update as a single request with a change in the navigation property for the categories indicated in the line, with other changes in the Person object. Can someone give me an example of how this can be done? In addition, you can show me how this would be done using the many to many property, unlike the one to many described above.

And finally, I am now using the detailed JSON format, V3. Would there be your answers to the above questions if I used the new JSON light format? If so, how?

+7
source share
3 answers

Pratik's comment was the answer (Pratik, if you want to convey this as an answer, I mark it as such - thanks!):

Question. Do you want to update a category instance or want to update some properties of a category instance. Unable to do later than package. For the first, you can do something like: {"Name": "new name", "Category": {"__metadata": {"uri": "/api.svc/Categories(2)"}}}. Hope this helps. - Practice

+4
source

I found two ways to represent the inline navigation properties:

application/json;odata=verbose - { "Name": "new name", "Category": { "__metadata": { "uri": "Categories(2)" }}}

application/json - { "Name": "new name", " Category@odata.bind ": "Categories(2)" }

+4
source

You no longer need a party. You can do it in one call. You just need to send the changed properties as well and let the repository handle the changed properties.

 public class Person { public string FirstName {get;set;} public string LastName {get;set;} public int Age {get;set;} } 

Say you notice that the first name has a typo, John, and it must be John. You can change the name and send it. So you have the following object model. You can get this in one of two ways:

  • Have two parameters and set BodyStyle = WebMessageBodyStyle.Wrapped
  • Just create a common model object with two properties: property one is of type T, and property 2 is a list.

So you would send this json:

 [{ FirstName = 'John' }, ['FirstName']] 

Now on the server side you can do what you need.

If you do not want to send changed properties, you can guess the changed properties by selecting any property whose value is not the default property.

{FirstName = 'John'}

You can then use several methods to see which properties have changed:

0
source

All Articles