In my previous article, I thought I found the solution. I was able to export and import a ribbon definition. The only thing I needed to do was to alter the xml in order to display my desired buttons. A straight forward job one would think.
*Wrong* I met the man with the hammer.
It turns out the there is a big difference in the XML described in my previous article, which is the XML Dynamics CRM expects in the solution import and the XML retrieved using the C# API call.
Dynamics CRM – Customizations.xml format
< CustomActions />
< Templates />
< CommandDefinitions />
< RuleDefinitions />
< LocLabels />
Dynamics CRM – XML returned by C# API call
When using the OrganizationRequest(“RetrieveEntityRibbon”) call from C# (like the code below):
OrganizationRequest req = new OrganizationRequest(“RetrieveEntityRibbon”);
The XML format returned looks like this.
<RibbonDefinitions> <RibbonDefinition> <UI> <Ribbon> … </Ribbon> </UI> <Templates> … </Templates> <CommandDefinitions> … </CommandDefinitions> <RuleDefinitions> … </RuleDefinitions> </RibbonDefinition> </RibbonDefinitions>
When I tried to import the XML generated by the API, I received an unexpected error (CRM can be helpful with its error messages). At first I was confused, but then it daunted upon me.
What if I create an empty solution and add the entity I need to it.
Then I can export it – which I already did to get the solution.xml and [content-types].xml – this time I can get the customizations.xml as well as it is filled with the entity I need.
As usual Google or Bing are my best friends, and after a short search I stumbled on a MSDN article in which an example of creating solutions and adding entities to it.
//Define a solution
var uniqueName = “DocumentIntegrationRibbon”;
var solution = new Entity(“solution”);
solution[“friendlyname”]=“Document Integration Ribbon”;
solution[“description”]=“This solution is used by the Document Integration”;
var solutionId = service.Create(solution);
var loadsolution = service.Retrieve(“solution”,solutionId, new ColumnSet());
// Add an existing Solution Component
//Add the Account entity to the solution
RetrieveEntityRequest retrieveForAddAccountRequest = new RetrieveEntityRequest()
LogicalName = “account”
RetrieveEntityResponse retrieveForAddAccountResponse = (RetrieveEntityResponse)service.Execute(retrieveForAddAccountRequest);
AddSolutionComponentRequest addReq = new AddSolutionComponentRequest()
ComponentType = 1, // entity
ComponentId = (Guid)retrieveForAddAccountResponse.EntityMetadata.MetadataId,
SolutionUniqueName = uniqueName
Running the code above and doing an export resulted in the XML structure I need, which is the format the solution import and export mechanism is using.
When I look back at this excercise, I learned a couple of things I want to share with you:
The XML returned by the C# API call returns the full blown XML used to draw the ribbons.
The XML described in the customizations.xml file describes the changes that have to be made to the ribbon in order to add the button.
We have to keep in mind the way Dynamics CRM is dealing with solutions and solution stacking:
The base ribbon + all managed RibbonDiffXml’s + all unmanaged RibbonDiffXml’s is the ribbon we see.
That is what we should keep in mind.