Skip to main content

Notifications

Announcements

No record found.

Microsoft Dynamics CRM (Archived)

Retrieve Metadata changes

Posted on by Microsoft Employee

Greetings,

I need to retrieve any changes in Dynamics metadata (ie, when a new value to an optionset is added).

This has to be done upon the change of the option set and not triggered from an entity-related event such as "Create" or "Update".

What is the best way to achieve that? My best guess is to write a C# plugin that will take care of this task.

Would you give me some suggestion on how to register the plugin correctly?

Thank you

*This post is locked for comments

  • Verified answer
    Community Member Profile Picture
    Community Member Microsoft Employee on at
    RE: Retrieve Metadata changes

    Hello again, I am using the following code to retrieve the optionsets that have changed however, when I try to read them I cannot get the name and more importantly I cannot detect if there have been any changes to it.

    What I would like to do is store the value of the ServerVersionStamp and use it to check whether an optionset has changed since then.

    How would I go to accomplish that?

    Below is the code that I am using:

    private OptionMetadata[] RetrieveOptionSet(IOrganizationService service, string globalOptionSetName)
      {
       RetrieveOptionSetRequest retrieveOptionSetRequest = new RetrieveOptionSetRequest { Name = globalOptionSetName };
       RetrieveOptionSetResponse retrieveOptionSetResponse = (RetrieveOptionSetResponse)service.Execute(retrieveOptionSetRequest);
       OptionSetMetadata retrievedOptionSetMetadata = (OptionSetMetadata)retrieveOptionSetResponse.OptionSetMetadata;
       OptionMetadata[] optionList = retrievedOptionSetMetadata.Options.ToArray();

       return optionList;
      }

      private void DetectOptionSetChanges(IOrganizationService service, IPluginExecutionContext context)
      {
       String[] excludedEntities =
       {
        "WorkflowLog",
        "Template",
        "CustomerOpportunityRole",
        "Import",
        "UserQueryVisualization",
        "UserEntityInstanceData",
        "ImportLog",
        "RecurrenceRule",
        "QuoteClose",
        "UserForm",
        "SharePointDocumentLocation",
        "Queue",
        "DuplicateRule",
        "OpportunityClose",
        "Workflow",
        "RecurringAppointmentMaster",
        "CustomerRelationship",
        "Annotation",
        "SharePointSite",
        "ImportData",
        "ImportFile",
        "OrderClose",
        "Contract",
        "BulkOperation",
        "CampaignResponse",
        "Connection",
        "Report",
        "CampaignActivity",
        "UserEntityUISettings",
        "IncidentResolution",
        "GoalRollupQuery",
        "MailMergeTemplate",
        "Campaign",
        "PostFollow",
        "ImportMap",
        "Goal",
        "AsyncOperation",
        "ProcessSession",
        "UserQuery",
        "ActivityPointer",
        "List",
        "ServiceAppointment"
       };

       MetadataFilterExpression EntityFilter = new MetadataFilterExpression(LogicalOperator.And);
       EntityFilter.Conditions.Add(new MetadataConditionExpression("IsIntersect", MetadataConditionOperator.Equals, false));
       EntityFilter.Conditions.Add(new MetadataConditionExpression("OwnershipType", MetadataConditionOperator.Equals, OwnershipTypes.UserOwned));
       EntityFilter.Conditions.Add(new MetadataConditionExpression("SchemaName", MetadataConditionOperator.NotIn, excludedEntities));

       MetadataConditionExpression[] optionsetAttributesTypes = new MetadataConditionExpression[] { new MetadataConditionExpression("AttributeType", MetadataConditionOperator.Equals, AttributeTypeCode.Picklist) };
       MetadataFilterExpression AttributeFilter = new MetadataFilterExpression(LogicalOperator.Or);
       AttributeFilter.Conditions.AddRange(optionsetAttributesTypes);

       MetadataPropertiesExpression EntityProperties = new MetadataPropertiesExpression() { AllProperties = false };
       EntityProperties.PropertyNames.AddRange(new string[] { "Attributes" });
       MetadataPropertiesExpression AttributeProperties = new MetadataPropertiesExpression() { AllProperties = false };
       AttributeProperties.PropertyNames.Add("OptionSet");
       AttributeProperties.PropertyNames.Add("AttributeType");

       int _languageCode = RetrieveUserUILanguageCode(service, context.UserId);
       LabelQueryExpression labelQuery = new LabelQueryExpression();
       labelQuery.FilterLanguages.Add(_languageCode);

       EntityQueryExpression entityQueryExpression = new EntityQueryExpression()
       {
        Criteria = EntityFilter,
        Properties = EntityProperties,
        AttributeQuery = new AttributeQueryExpression()
        {
         Criteria = AttributeFilter,
         Properties = AttributeProperties
        },
        LabelQuery = labelQuery
       };

    //I would like to store and retain the timestamp in order to check for changes   

       RetrieveMetadataChangesResponse initialRequest = getMetadataChanges(service, entityQueryExpression, clientVersionStamp, DeletedMetadataFilters.OptionSet);

       string temp = string.Empty;
       if (initialRequest.Results.Values != null)
        foreach (EntityMetadata item in initialRequest.EntityMetadata) // I believe the mistake is here. How would I read what option set has changed and what value.
        {
         temp += item.HasChanged + "\n";
        }
       else
        throw new InvalidPluginExecutionException("metadata has not changed");

       throw new InvalidPluginExecutionException("count: " + initialRequest.EntityMetadata.Count + "\nattributes: " + temp);

      }

      protected int RetrieveUserUILanguageCode(IOrganizationService service, Guid userId)
      {
       QueryExpression userSettingsQuery = new QueryExpression("usersettings");
       userSettingsQuery.ColumnSet.AddColumns("uilanguageid", "systemuserid");
       userSettingsQuery.Criteria.AddCondition("systemuserid", ConditionOperator.Equal, userId);
       EntityCollection userSettings = service.RetrieveMultiple(userSettingsQuery);
       if (userSettings.Entities.Count > 0)
       {
        return (int)userSettings.Entities[0]["uilanguageid"];
       }
       return 0;
      }
      
      protected RetrieveMetadataChangesResponse getMetadataChanges(
       IOrganizationService service,
       EntityQueryExpression entityQueryExpression,
       string clientVersionStamp,
       DeletedMetadataFilters deletedMetadataFilter
       )
      {
       RetrieveMetadataChangesRequest retrieveMetadataChangesRequest = new RetrieveMetadataChangesRequest()
       {
        Query = entityQueryExpression,
        ClientVersionStamp = clientVersionStamp,
        DeletedMetadataFilters = deletedMetadataFilter
       };

       return (RetrieveMetadataChangesResponse)service.Execute(retrieveMetadataChangesRequest);

      }

  • Community Member Profile Picture
    Community Member Microsoft Employee on at
    RE: Retrieve Metadata changes

    Alessandro Graps 

    Thank you for your reply. I found the article very useful to start, however how would I call this method? Is there a way to make the plugin listens to metadata changes?

    As of now I know how to register the plugin for entities and records' changes. Any suggestion on that?

  • Suggested answer
    Alessandro Graps Profile Picture
    Alessandro Graps 2,664 on at
    RE: Retrieve Metadata changes

    Hi,

    I agree with you. you can use a plugin with c#. Here there is an example to retrieve only change in metadata msdn.microsoft.com/.../jj863599.aspx

    Thanks

    A.G.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

December Spotlight Star - Muhammad Affan

Congratulations to a top community star!

Top 10 leaders for November!

Congratulations to our November super stars!

Tips for Writing Effective Suggested Answers

Best practices for providing successful forum answers ✍️

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 291,280 Super User 2024 Season 2

#2
Martin Dráb Profile Picture

Martin Dráb 230,235 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,156

Leaderboard

Featured topics

Product updates

Dynamics 365 release plans