My plugin doesn't work when i set it to be synchrounous, it says that it entered a infinite loop on the error message, when i debug it i don't see any error, when i set to Async it works.
One thing i noticed, when it's set to Async, the plugin will run 1 one time on the create step and a few times (6~8) on the update step (the last one fails, informing about the infite loop), but i only created the case, i didn't updated and my workflows don't touch the fields that were supposed to trigger the update case step of the plugin. The plugin is filtered for only 2 fields (customerid and subjectid) that are not changed by my plugin, so i don't know why it keeps calling the plugin again and again.
This is my code:
public class CaseContractFill : IPlugin { Contract checkForContract(Guid accountId, IOrganizationService service) { //Bring all contracts associated with a account QueryExpression accountContractQuery = new QueryExpression { EntityName = Contract.EntityLogicalName, ColumnSet = new ColumnSet(true), Criteria = new FilterExpression { Conditions = { new ConditionExpression { AttributeName = "accountid", Operator = ConditionOperator.Equal, Values = { accountId } } } } }; DataCollection<Entity> accountContracts = service.RetrieveMultiple(accountContractQuery).Entities; //Check if account has a Active or Invoiced contract and return it if (accountContracts.Count > 0) { foreach (Contract item in accountContracts) { if (item.StateCode == ContractState.Active || item.StateCode == ContractState.Invoiced) { return item; } } } //Retrieves account information Account account = (Account)service.Retrieve(Account.EntityLogicalName, accountId, new ColumnSet(true)); //Check if account has a parent and call this method again with that parent if (account.ParentAccountId != null) { return checkForContract(account.ParentAccountId.Id, service); } //If no Contract and/or no Parent returns null return null; } ContractDetail checkForContractLine(Guid contractId, Incident incident, IOrganizationService service) { //Query to bring all contract lines from a contract id QueryExpression accountContractQuery = new QueryExpression { EntityName = ContractDetail.EntityLogicalName, ColumnSet = new ColumnSet(true), Criteria = new FilterExpression { Conditions = { new ConditionExpression { AttributeName = "contractid", Operator = ConditionOperator.Equal, Values = { contractId } } } } }; DataCollection<Entity> contractLines = service.RetrieveMultiple(accountContractQuery).Entities; ContractDetail contractLine = null; // Check all contract lines to find one that matches the Case subject with the contract line product name, if none is found, returns a active one foreach (ContractDetail item in contractLines) { if ((item.StateCode == ContractDetailState.Existing) || (item.StateCode == ContractDetailState.Renewed)) { if ((incident.SubjectId != null) && (item.ProductId != null)) { if (incident.SubjectId.Name.Equals(item.ProductId.Name)) { contractLine = item; break; } contractLine = item; } } } return contractLine; } public void Execute(IServiceProvider serviceProvider) { ITracingService tracer = (ITracingService)serviceProvider.GetService(typeof(ITracingService)); IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext)); IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); IOrganizationService service = factory.CreateOrganizationService(context.UserId); try { Entity entity = (Entity)context.InputParameters["Target"]; Incident incident = (Incident)entity.ToEntity<Incident>(); incident = (Incident)service.Retrieve(Incident.EntityLogicalName, incident.Id, new ColumnSet(true)); Contract contract = checkForContract(incident.CustomerId.Id, service); if (contract != null) { incident.ContractId = contract.ToEntityReference(); ContractDetail contractLine = checkForContractLine(contract.Id, incident, service); if (contractLine != null) { incident.ContractDetailId = contractLine.ToEntityReference(); } service.Update(incident); } } catch (Exception e) { throw new InvalidPluginExecutionException(e.Message); } } }