OData / AspNetCoreOData

ASP.NET Core OData: A server library built upon ODataLib and ASP.NET Core
Other
457 stars 158 forks source link

Inconsistent handling of navigation properties between PUT and PATCH #172

Open dxrdxr opened 3 years ago

dxrdxr commented 3 years ago

AspNetCoreOData 8.0.0 latest nightly

Create an Entity that has a navigation property:

POST http://localhost:5000/odata/People
{
    "ID": 999,
    "Name": "Some Great Company",
    "Contact@odata.bind": "/Contacts(42)",
    "Certifications@odata.bind": [
        "Certifications('Apprentice')",
        "Certifications('Master')"
    ]
}

Update it using PUT:

PUT http://localhost:5000/odata/People(666)
{
    "Name": "Some Other Great Company",
    "Certifications@odata.bind": [
        "Certifications('Junior')",
        "Certifications('Senior')"
    ]
}

The PeopleController.Put method receives as an argument the person class that includes the navigation property.

Now using Patch:

PUT http://localhost:5000/odata/People(666)
{
    "Name": "Yet Other Great Company",
    "Certifications@odata.bind": [
        "Certifications('Mom')",
        "Certifications('Dad')"
    ]
}

The PeopleController.Patch method receives as an argument the person class that does NOT includes the navigation property.

This raises a couple questions:

  1. Why the inconsistency? The workaround is to use Put or CreateRef and DeleteRef
  2. In the OData 4.01 standard here it says: "Deep inserts are not allowed in update operations using PUT or PATCH requests." By my informal interpretation this would mean that the currently implemented Put semantics is wrong and Patch is correct.

I have not tested the 7.X behavior so I don't know if this is existing behavior.

@mikepizzo

xuzhg commented 3 years ago

@dxrdxr @odata.bind is a new feature in 7.x which is still under development.

8.0, I implemented "parts" of @odata.bind. "Patch" could not be implemented yet.

I will take a look and update you later. If you can share your repro, it will be better.