Tip #970: When attribute and entity collide

This tip is from Martin Tölk.

If the name of an attribute on a custom entity matches the name of the entity itself then you will not find that attribute in the metadata returned by WebAPI. Dynamics 365 will play the games with your brain by adding ‘1’ to the attribute name, presumably to avoid clashes.

For example, if you define an entity:

Entity name

and include an attribute with the same name (we use primary attribute, the same as Martin did, but the problem is reproducible on any attribute):

Attribute name

and then attempt to get the data using WebAPI: https://org.crm.dynamics.com/api/data/v8.2/new_locationcodes?$select=new_locationcode, you will get an error “Could not find a property named ‘new_locationcode'”.

Try getting all attributes by removing $select (and adding $top to keep it short): https://org.crm.dynamics.com/api/data/v8.2/new_locationcodes?$top=1, and you’ll find that the attribute was magically renamed to new_locationcode1:

{
  "@odata.context":".../$metadata#new_locationcodes",
  "value":[
  {
    "@odata.etag":"W/\"69645573\"",
    ...
    "new_locationcode1":"Foobar",
    ...
  }]
}

Ugh. The easiest way to avoid this headache is to avoid naming clashes in the first place.

Be smart, be like Martin and send us your tips via Facebook Messenger or simply email jar@crmtipoftheday.com.

7 thoughts on “Tip #970: When attribute and entity collide

  1. The easiest way to avoid this is to not rename the primary field name at all.

  2. AdamV says:

    Every entity has the primary key (GUID) in an attribute which has the same name as the entity display name (when first created) and schema name as prefix_entityname. So if you create an attribute with the same name as the entity display name, there would be a conflict. Seems like there should be an error message at create time though, rather than a silent and secret renaming in the background.

    • Schema name for the primary key is prefix_entitynameId so there is no conflict.

      • AdamV says:

        Fair enough the schema name has ID on the end, but the display names would still be the same, so it is probably best to avoid using the entity name as a field/attribute name to avoid having two fields which are indistinguishable in the UI. Definitely not “best practice” in my book.
        I think I always figiured the issue was that if the display names were the same then the system assumed that would result in identical schem names so changed it internally, despite the fact that there was no conflict in reality. Jatin’s explanation seems more sensible, although frustratingly undocumented as you say.

        It’s also a matter of semantics and pedantry for me – if you have an entity, say, “Country” then the primary field cannot be properly called “Country” – this is not the Country of the Country, it is simply the *name* of the country (or ISO code, or whatever). Similarly a Vehicle would have a registration / VIN number, you would not call this field “Vehicle”. Project does not have a “Project” as a property, it has a project name, or a project number or something else.
        In some cases they might have a lookup field for something like a Parent Project, but that would be called something specific rather than just “Project” to avoid ambiguity.

  3. Jatin Sanghvi says:

    The decision to append ‘1’ to the property name was made as a workaround for limitation in OData.NET 6.15.0 library that an entity type cannot contain a property with same name. I could not locate an issue on https://github.com/OData/odata.net/issues to reference here.

    The forthcoming Dynamics 365 release that’s under development, builds with the latest OData.NET library that has this bug addressed. You should not see ‘1’ appended if the requests are made on Web API’s v9.0 service endpoint.

    For v8.x endpoints, the property name would still contain ‘1’ to ensure compatibility that the v8 OData clients is maintained. Following URL should not return error:

    https://org.crm.dynamics.com/api/data/v9.0/new_locationcodes?$select=new_locationcode

    • That’s great, Jatin, thanks for the explanation. I know it’s the edge case but the whole kerfuffle probably could’ve been avoided by adding something to the documentation 🙂
      Cheers
      George

Leave a Reply

Your email address will not be published. Required fields are marked *