Search code examples
asp.net-web-apiodata

OData V4 (webapi) patch with NavigationProperty collection breaks deserailization on server


I’m trying to go against a Web API Patch method that accepts a Delta. My entity has a navigational property that is a collection. The domain model is trivial, I have a team (entity) and a collection of members (navigational property).

I’m using HttpClient directly instead of the OData client.

The problem I’m running into is that when I send a patch request with the payload = a Team, the Delta deserialized in my controller is null when I include the navigational property collection in my payload.

Eg (ignore that the missing quotes, this is typed in}:

{ Name: Foo } -> serializes to Delta successfully. {Name: Foo, Members : [] } -> fails to serialize and Delta is null.

Is this supported? I could not find concrete documentation online about whether you can supply navigational properties as an entire collection on patch (not looking for merge support, just want full replace of the collection.)

I also tried tweaking my client to directly send a Delta payload, but the default JsonMediaTypeFormatter is unable to serialize this into a valid request body (always produces empty Json), and the ODataMediaTypeFormatter throws an exception saying it cannot write an object of type Delta, although I have initialized it with every ODataPayloadKind.

I’m sure I’m either doing something wrong or missing something basic, assuming using Delta + patch with HttpClient is not this challenging.


Solution

  • For OData spec, it says:

    11.4.3 Update an Entity

    ... The entity MUST NOT contain related entities as inline content. It MAY contain binding information for navigation properties. For single-valued navigation properties this replaces the relationship. For collection-valued navigation properties this adds to the relationship.

    That is you can't put the navigation properties in the Patch request content.

    From Web API OData, it has these codes and these codes. It means that it doesn't allow to patch navigation property form entity.

    However, you can shoot your target by following steps:

    1. Patch the principal entity (team)
    2. Patch the dependent entities (members)
    3. use the $ref to update the link

    You can refer to my simple test project.