Misadventures in API Design

So, my most recent project has been integrating the Microsoft Dynamics CRM with an onsite customer system. The details of which aren’t that interesting, at least to this blog post.

The project i am creating uses a class supplied by the dynamics team ( I think ) called the OrganizationServiceProxy (in the Microsoft.Xrm.Sdk Nuget Repository). This class, which is a double word score in bad naming bingo, lets you interact with entities on the server. One of these entities is an account, also called a client in normal speak.

Each account has an owner, which is the employee that is responsible for the account. Again nothing shocking as of yet. The problem arises when you go to change the owner from the legacy system. There is a simple procedure for changing the vast majority of the properties on the account object. Set the property using a simple assignment then when you’ve set al the properties you want to change send the updateRequest.

So, I went to change the owner of an account. Typed account. and looked for owner, there isn’t a property (Warning 1). There is an account.ownerId, perfect, thats easier for me to find…

20120924-155957.jpg

[sourcecode language=”csharp”]
account.OwnerId = new EntityReference(SystemUser.EntityLogicalName, new Guid());
[/sourcecode]

Then I looked at the Type of OwnerId, Its a EntityReference. (Strike 1)
So i go to hydrate the entity Reference, It takes a string and a guid.

The string they are looking for is the table name, precisely formatted. This is clearly Strike 2. There are at least 3 options for how you could do this better,

  1. UserReference that inherits EntityReference
  2. Still Use Entity Reference but instead of a string take an enum that gives you the options
  3. Just take the Guid, or is the fact that its globally unique (within reason) not give you enough identification of the record I want

Fine … I have set it. Go to see it in practice. Change the owner in the legacy system and the address.
Check CRM .
no change in either.
wait 10 seconds, address has changed. Owner has not.

Check for errors. None. Check for warnings. None.

Try it again, same results. scratch head.

Then realize that in order to change the owner you need to post a assignmentRequest.

[sourcecode language=”csharp”]
var service = (IOrganizationService) organizationProxy;
var asignee = new EntityReference(SystemUser.EntityLogicalName, user);
var target = new EntityReference(Account.EntityLogicalName, accountId);
var req = new AssignRequest
{
Assignee = asignee,
Target = target
};
service.Execute(req);
[/sourcecode]
20120924-160006.jpg

So there is a property that does nothing when set but is not read only, that doesnt warn you that it does nothing. Thats Strike 3 and Strike 4 ( this is clearly foreign rules baseball)

Youtube explanation of foreign rules baseball

This was not easily discoverable and took me hours to figure out. I may not be the smartest dev but that is clearly a fault in the system as well.

I feel that there is now more light on the particular issue. Hopefully this helps someone. If not the people who design systems like this.

He, too, must cross in the twilight dim;
Good friend, I am building this bridge for him!”

Source Reference (Its a good poem)