Of course it is possible to create some special integration account and not track all changes applied under this account. My idea was to reuse existing Integration account. Following code I use in synchronization service to create instance of IOrganizationService and impersonate as ‘Integration’ user:
private static IOrganizationService GetOrganizationService(Uri serviceUrl, NetworkCredential credential) { ClientCredentials credentials = new ClientCredentials(); credentials.Windows.ClientCredential = credential; OrganizationServiceProxy proxy = new OrganizationServiceProxy(serviceUrl, null, credentials, null); QueryByAttribute query = new QueryByAttribute("systemuser"); query.AddAttributeValue("fullname", "integration"); query.ColumnSet = new ColumnSet(false); DataCollection<Entity> users = proxy.RetrieveMultiple(query).Entities; if (users.Count == 0) throw new Exception("Integration user was not found!"); proxy.CallerId = users[0].Id; return (IOrganizationService)proxy; }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Query; using System.Data.SqlClient; namespace XRMSolutions.Plugins { public class OperationHandler : IPlugin { #region Privates private Guid _integrationUserId = Guid.Empty; #endregion Privates #region IPlugin members public void Execute(IServiceProvider serviceProvider) { IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext)); #region Integration User Lookup if (_integrationUserId == Guid.Empty) { IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); IOrganizationService crmservice = serviceFactory.CreateOrganizationService(null); QueryExpression query = new QueryExpression("systemuser"); query.ColumnSet = new ColumnSet(false); query.Criteria.AddCondition("fullname", ConditionOperator.Equal, new object[] { "integration" }); EntityCollection users = crmservice.RetrieveMultiple(query); if (users.Entities.Count == 0) return; _integrationUserId = (Guid)users[0]["systemuserid"]; } #endregion Integration User Lookup if (context.UserId == _integrationUserId) return; //Here you should put code which would be used for tracking of changed data } #endregion IPlugin members } }
It's better to use IntegrationUserId attribute of the Organization entity to determine id of a system account.
ReplyDeletep.s. You can get OrganizationId from plugin context.
Thanks, your opinion is very important for me!
Delete