simple-odata-client / Simple.OData.Client

MIT License
331 stars 197 forks source link

Updating a Navigation Link seems to generate an incorrect odata.bind value #286

Open DuncanMillard opened 8 years ago

DuncanMillard commented 8 years ago

I'm not sure if this is an issue with the Simple Odata Client, or with the way odata (and in particular entity pluralization) is implemented by this server app...

I'm trying to update a Navigation Link with the following code:

var newAssignmentStatus = await crmODataclient
                    .For(query.assignmentstatuses)
                    .Filter(query.name == "Left")
                    .FindEntriesAsync();
(snip - extract result into "assignmentStatus" variable) 
                var update = await crmODataclient.For(query.resourceassignments)
                    .Filter(query.resourceassignmentid == assignmentKey)
                    .Set(query.assignmentstatus = assignmentStatus)
                    .UpdateEntryAsync();

The odata.bind value PATCHed back uses the singular name for the linked assignmentstatus entity rather than the plural name.

So the data passed to the server is:

{
  "@odata.type":"#Microsoft.Dynamics.CRM.resourceassignment","assignmentstatus@odata.bind":"http://<base url>/assignmentstatus(6c4bdd4f-a97f-42df-bbbf-4cb6412e3862)"
}

it should be:

{
  "@odata.type":"#Microsoft.Dynamics.CRM.resourceassignment","assignmentstatus@odata.bind":"http://<base url>/assignmentstatuses(6c4bdd4f-a97f-42df-bbbf-4cb6412e3862)"
}

If I examine the annotations for the assignmentStatus object, the ReadLink, Id and EditLink all use the plural form of the name to refer to the entity - seems it should be using this in generating the link value too?

DuncanMillard commented 8 years ago

Bit more research: if I intercept at RequestWriter.cs @ line 333

var linkedCollectionName = _session.Metadata.GetLinkedCollectionName(
                        referenceLink.LinkData.GetType().Name, linkTypeWithKey.Name, out isSingleton);

and manually force linkedCollectionName to be the plural version, then the correct PATCH request is generated and the data is updated on the server.

DuncanMillard commented 8 years ago

OK - got it - the suffix "status" isn't correctly pluralised to "statuses" by the pluralizer, so the Entity Collection lookup in TryGetEntitySet fails to match:

entitySet = _model.SchemaElements
                .Where(x => x.SchemaElementKind == EdmSchemaElementKind.EntityContainer)
                .SelectMany(x => (x as IEdmEntityContainer).EntitySets())
                .BestMatch(x => x.Name, entitySetName, _session.Pluralizer);

The above returns null instead of the assignmentstatuses entity set.

Could either add "status" to the hardcoded suffixes list, or allow a custom set of suffixes/plurals to be passed in whe constructing the ODataClientSettings instance. I'll try and get a pull request together for the latter but it won't be for a while.