I have been writing some code which works with CRM Metadata and it has been interesting.
Years ago when I first heard the term Metadata I didn’t really understand what it was and more importantly why it was useful. The other thing which bugged me about metadata is the letter d is not capitalised and it looks a bit shifty to me.
The person who first mentioted metadata wase saying it was data about data. I remember thinking
“so it’s not the data itself, its data about the data, why do I want to know that?”
Let’s start with our good friend Wikipedia for a definition of a Metadata
Metadata is “data about data”.[1] There are two “metadata types;” structural metadata, about the design and specification of data structures or “data about the containers of data”; and descriptive metadata about individual instances of application data or the data content.
To understand the importance of Metadata read these articles
What is Metadata, and Why is it Important?
A quick Hosk summary of Metadata
- An index in a book is Metadata, it helps you categorise/segment the information
- Metadata is the characteristics of the data e.g. data type, length, description
- It can show the relationships between data
- Metadata allows efficiently classify and a structured way to organise data for ease of use
Examples of Metadata
SharePoint holds metadata on documents so when people want to search they can search for one type of document
indexes in books, to help you find the information for a certain area
Library sort books by type, this is metadata
What Metadata does CRM hold
CRM holds metadata for
Entities
It holds Metadata for fields such as (I am only going to list some of the more interesting fields available not all of them)
- LogicalName
- DisplayName
- SchemaName
- AttributeType
- IsAuditEnabled
- IsRenameable
- IsManaged
- IsPrimaryId
Looking at the list above, possibilities of use and uselessness should already be flowing through your brain.
I can see which fields are audited?
I can see which fields are managed?
To see the full list of Metadata attributes you can view this page of the Metadata properties
The metadata in CRM is not only focused on Entities and Attributes, CRM holds metadata on entity relationships and entity and attribute mappings.
How Does CRM store the data
I found CRM SDK a little bit confusing when it came to understanding how the Metadata is stored in CRM and how to get it. There are some good articles on CRM Metadata but they are held in different locations
If you do an internet search you get pages which are a little bit helpful but all the information seems to be in small bits and scattered over various pages. This result was it took me a bit longer to get my head around using Metadata.
I will try and simplify the process for you and group together the material in the CRM SDK in a more logical structure.
CRM holds Metadata at Entity and Attribute level.
e.g. You can get Metadata for the incident entity
e..g You can get Metadata for the attributes/fields which exist for the incident entity.
CRM holds metadata for Relationships
CRM holds metadata for entity and attribute mappings
Start with Microsoft.Xrm.Sdk.Metadata
To see What Metadata information is stored start with this page Microsoft.Xrm.Sdk.Metadata, this page shows all the Metadata classes and all the Metadata you can retrieve.
I found the page above confusing because it seemed like there was loads of Metadata you can retrieve and seeing all the classes in flat structure didn’t make it clear how they interacted with each other.
This page is a good page to understand the Metadata model in CRM
The metadata and data models in Microsoft Dynamics CRM
Microsoft.Xrm.Sdk.Metadata Namespace
You can see the different types of attribute Metadata below
[KnownTypeAttribute(typeof(StringAttributeMetadata))] [KnownTypeAttribute(typeof(StateAttributeMetadata))] [KnownTypeAttribute(typeof(MoneyAttributeMetadata))] [KnownTypeAttribute(typeof(IntegerAttributeMetadata))] [KnownTypeAttribute(typeof(BigIntAttributeMetadata))] [KnownTypeAttribute(typeof(UniqueIdentifierAttributeMetadata))] [KnownTypeAttribute(typeof(BooleanAttributeMetadata))] [KnownTypeAttribute(typeof(DateTimeAttributeMetadata))] [KnownTypeAttribute(typeof(DecimalAttributeMetadata))] [KnownTypeAttribute(typeof(DoubleAttributeMetadata))] [KnownTypeAttribute(typeof(EntityNameAttributeMetadata))] [KnownTypeAttribute(typeof(ImageAttributeMetadata))] [DataContractAttribute(Name="AttributeMetadata", Namespace="http://schemas.microsoft.com/xrm/2011/Metadata")] [KnownTypeAttribute(typeof(LookupAttributeMetadata))] [KnownTypeAttribute(typeof(MemoAttributeMetadata))] [KnownTypeAttribute(typeof(PicklistAttributeMetadata))] [KnownTypeAttribute(typeof(StatusAttributeMetadata))] [KnownTypeAttribute(typeof(ManagedPropertyAttributeMetadata))] public class AttributeMetadata : MetadataBase
- EntityMetadata class
- AttributeMetadata class
- LookupAttributeClass
- DecimalAttributeClass
- PicklistAttributeClass
- StatusAttributeClass
- All the other attribute classes
- AttributeMetadata class
EntityMetadata is metadata for the entity.
AttributeMetadata class is the base class for attributeMetaData and then there are lots of individual attributeMetaData types (e.g. for all the different CRM field types)
The easiest way to visualise how the metadata fits together is compare them to Entities and fields.
e.g. an Entity record has Attributes collection which contains a list of fields
EntityMetadata has a attributes collection which contains a list of AttributeMetadata fields.
Getting Started with Metadata
As Always when doing CRM Development you should always start first with the SDK, the page below is a great place to start
Use the IOrganizationService web service to read and write data or metadata
In Microsoft Dynamics CRM 2015, the primary web service that accesses data and metadata for your organization is IOrganizationService. This web service contains the methods that you use to write code that uses all the data and metadata in Microsoft Dynamics CRM.
I’m not sure when this change happened but I’m sure in older versions of CRM (CRM 4 I think) there was a metadata service which you had to use to retrieve Metadata but now you can use the IOrganizationService, which is easier to use.
The CRM SDK has decent sample code
Sample: Create and update entity metadata
Here is another sample
Sample: Dump entity metadata to a file
Sample code below retrieve the metadata for the incident metadata record
try { RetrieveEntityRequest request = new RetrieveEntityRequest { EntityFilters = EntityFilters.Attributes, LogicalName = 'incident' }; RetrieveEntityResponse response = (RetrieveEntityResponse) crmService.Execute(request); this.entityMetaData = response.EntityMetadata; } catch (Exception ex) { throw new throw new InvalidPluginExecutionException(ex); }
the code below converts the entityMetaData to a list and then searches the attributeMetaData (which holds the individual field metadata for the incident entity). The code matches the logicalName of the attributeMetaData records with a string value, in the code I was checking to see if a field existed and then later was checking the field was of a correct type.
List<AttributeMetadata> attributeMetadata= entityMetaData.Attributes.ToList();
var fieldExists = attributeMetadata.Where(p => p.LogicalName == field.ToLower());
This MSDN article shows you how to retrieve a single metadataattribute
https://msdn.microsoft.com/en-us/library/gg509025.aspx
// Use the RetrieveAttributeRequest message to retrieve // a attribute by it's logical name. RetrieveAttributeRequest retrieveAttributeRequest = new RetrieveAttributeRequest { EntityLogicalName = Contact.EntityLogicalName, LogicalName = "new_picklist", RetrieveAsIfPublished = true }; // Execute the request. RetrieveAttributeResponse retrieveAttributeResponse = (RetrieveAttributeResponse)_serviceProxy.Execute( retrieveAttributeRequest); // Access the retrieved attribute. PicklistAttributeMetadata retrievedPicklistAttributeMetadata = (PicklistAttributeMetadata) retrieveAttributeResponse.AttributeMetadata; // Get the current options list for the retrieved attribute. OptionMetadata[] optionList = retrievedPicklistAttributeMetadata.OptionSet.Options.ToArray();
Retrieving one column or all the columns is similar to using the ColumnSet in a queryExpression.
If you specify all you get all the AttributeMetadata (e.g. the fields for the entity) and if you specify a column then it will return one column.
Common uses of CRM Metadata
Retrieving OptionSet string value
One of the common uses for Metadata is to retrieve the string value of an optionset. OptionSets are stored in the CRM database as Int numbers and the string values are in the Metadata.
This makes sense but can be a little bit annoying, interestingly FilteredViews bring store the string name and the int value. Learn more about filtered views in my article below
CRM 2015 – Why filtered views are useful
If you need to retrieve the string of an OptionSet this blog will show you how
Retrieve Option Set Selected Text Value in CRM 2011
Integrating websites/application
The CRM SDK allows you to do CRUD (Create, Read, Update and Delete). This allows developers to show and manipulate CRM data in a website/application/WCF web service.
When your custom applications are dealing with entities and fields it will be important to know what type of field they are and other data like (are they managed, read only etc). You can retrieve the metadata information and use it your application
The MSDN article The metadata and data models in Microsoft Dynamics CRM, makes some good points
The Microsoft Dynamics CRM Web services contain the messages that you use to read or write the definitions for all the entities each organization. It can also be used to build a client-side metadata cache, which is useful for applications that access the metadata frequently. For example, you may want to create a custom search solution that supports all entities, even those created after the solution has been installed.
A very important role of the metadata is to provide the framework to deliver a fully metadata driven user interface. The entity metadata controls the grid and form layout, and how navigation options are presented.
Extending the Metadata
I haven’t done this myself but it’s possible to update Metadata using the IOrganizationService. If you are interested in this, I will point you to the MSDN article
- You can customize entity and attribute metadata
- Customize entity and relationship
- Customize entity and attribute mappings
- Customize labels to support multiple languages