Hi,
I am running into an issue with plug-in dependency. Can some one provide a resolution for this problem.
I have created a generic plug-in that creates connection record for Lead or Opportunity. I have registered the plug-in on Lead and Opportunity create. There are 2 scenarios where a dynamic connection get created.
I have one more plug-in that is registered on Connection entity create as well.
1. Dynamically create the connection when a lead or opportunity record is created. I registered this plug-in on Lead and Opportunity create step. There is some business logic that will change the Connection Role and creates it. This works fine if the second plug in mentioned in point 2 is disabled.
2. I have another plug-in registered on Connection entity for create step. There is some business logic when the user manually saves a connection record from connection form.
These two are conflicting each other and when i save the Lead Record the second plug-in that is registered against connection create step also getting called and erroring out.
I am trying to disable the second plug-in that is registered on Connection create step whenever the Lead record is getting created. I dont want to disable the second plug-in and enable it after the record is created but i felt thats the only option to make it work but some times its working and some times its not working. May be because of the plug-in refresh during Enable/Disable not sure yet.
Is there any way i can create this dependency and dont call the 2nd plug-in that i registered on connection entity whenever the lead record is created?
*This post is locked for comments
Hi SVN,
I am confused :(.
In your questions you said you have generic plugin which triggers on create of Lead, Connection & Opportunity but the ode doesn't have opportunity part. You said you have another plugin which triggers on connection create, what does that look like?
Also, as per you code, you are creating connection in plugin and also have a step registered for the same plugin on create of connection. I think this will go into the infinite loop thingy.
You mentioned it is working fine when you are debugging, Did you try to use Depth in your plugin. see if it helps.
=====
if (context.Depth > 1)
======
I always try to make things simple instead of getting into making the things "Generic" and then banging my head when its not working.
Hope this helps.
Thanks Alex. Yes i am setting the connection role. I figured that the problem is with the record1 attribute check.
Hi SVN,
it's a big piece of code, so.. But do you have a connection role for those two record types?
You said it's not failing when you are debugging - were you using "replay plugin execution" option (in which case it would not be creating any records)
Thanks Ravi. I am getting this error "The record type 1 is not defined for use with the connection role" but if i disable the plug-in on Connection entity and refresh the page then it works fine. If i enable the connection entity plug-in then i am getting this error. I followed the execution order Lead Plugin 1 and Connection Plug in 2 that are registered for Create step. Both are registered on sync /Post. Individual plug-in works fine. I tried by separating the code into two different plug-in but couldn't get much help. Same plug-in works fine for Opportunity create as well. I can create the opportunity and Connections separately but the Lead plug-in is not working.
Thanks Alex. I tried that option as well. I was getting "The record type 1 is not defined for use with the connection role" error but when i was debugging both the plug-ins it doesn't show error once and doesn't create the record that it needs to create. Here is the generic code that i am using and registered on Lead Create and Connection Create plug-ins. Can you suggest any other alternatives or some thing wrong with this approach that i followed?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using System.ServiceModel;
using System.Runtime.Serialization;
using System.Web;
using System.Xml;
using Microsoft.Crm.Sdk.Messages;
namespace LeadConnection
{
public class LeadConnection : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IExecutionContext));
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
Entity entity = (Entity)context.InputParameters["Target"];
string connectionCheck = string.Empty;
if (entity.Attributes.Contains("sm_createconnectioncheck"))
{
connectionCheck = entity.Attributes["sm_createconnectioncheck"].ToString();
}
if (entity.LogicalName == "lead")
{
CreateDefaultConnection(service, tracingService, context, entity);
}
else if (entity.LogicalName == "connection" && connectionCheck != "No")
{
CreateConnection(service, tracingService, context, entity);
}
}
public void CreateDefaultConnection(IOrganizationService service, ITracingService tracingService, IPluginExecutionContext context, Entity entity)
{
try
{
string message = context.MessageName.ToLower();
string amrAccountUser = string.Empty;
if (entity.LogicalName == "lead")
amrAccountUser = entity.Attributes["sm_clientgroup"].ToString();
else if (entity.LogicalName == "opportunity")
amrAccountUser = entity.Attributes["sm_clientgroup_opp"].ToString();
Guid contactid = ((EntityReference)entity.Attributes["parentcontactid"]).Id;
if (contactid == null)
return;
if (amrAccountUser == "BGT" && (message == "create"))
{
Guid id = Guid.NewGuid();
if (entity.LogicalName == "lead")
id = (Guid)entity.Attributes["leadid"];
else if (entity.LogicalName == "opportunity")
id = (Guid)entity.Attributes["opportunityid"];
QueryExpression query = new QueryExpression("contact");
EntityCollection Result = null;
var columnNames = new[] { "fullname", "emailaddress1" };
FilterExpression filterExpression = new FilterExpression(LogicalOperator.And);
filterExpression.AddCondition("contactid", ConditionOperator.Equal, contactid);
query.ColumnSet.AddColumns(columnNames);
query.Criteria = filterExpression;
query.LinkEntities.Add(new LinkEntity("contact", "account", "parentcustomerid", "accountid", JoinOperator.LeftOuter));
query.LinkEntities[0].Columns.AddColumn("psm_accounttype");
query.LinkEntities[0].Columns.AddColumn("accountid");
query.LinkEntities[0].Columns.AddColumn("accountnumber");
Result = service.RetrieveMultiple(query);
string accountType = Result.Entities[0].FormattedValues["account1.psm_accounttype"].ToString();
string associatedAccount = "";
if (Result != null && Result.Entities.Any())
associatedAccount = ((AliasedValue)Result.Entities[0]["account1.accountid"]).Value.ToString();
else
return;
Guid accountid = new Guid(associatedAccount);
string connectionRoleValue = "";
if (accountType == "Test Broker")
{
connectionRoleValue = "Test Broker 1111";
}
else if (accountType == "Test Broker2")
{
connectionRoleValue = "Test Broker 22222";
}
else
{
connectionRoleValue = "Default";
}
EntityCollection connectionResult = GetConnectionRole(service, connectionRoleValue);
if (connectionResult == null || !connectionResult.Entities.Any())
return;
Entity connection = new Entity();
connection.LogicalName = "connection";
if (entity.LogicalName == "lead")
connection.Attributes.Add("record1id", new EntityReference("lead", id));
else if (entity.LogicalName == "opportunity")
connection.Attributes.Add("record1id", new EntityReference("opportunity", id));
connection.Attributes.Add("record2id", new EntityReference("account", accountid));
connection.Attributes.Add("record2roleid", new EntityReference("connectionrole", new Guid(connectionResult.Entities[0].Attributes["connectionroleid"].ToString())));
connection.Attributes.Add("sm_createconnectioncheck", "No");
service.Create(connection);
}
}
catch (FaultException<OrganizationServiceFault> ex)
{
tracingService.Trace("Error Occurred in Create Lead Connection Plugin: " + ex.Message);
throw new InvalidPluginExecutionException("An error occurred in the Lead Connection Plugin.", ex);
}
catch (Exception ex)
{
tracingService.Trace("Error Occurred in Create Lead Connection :", ex);
throw;
}
}
private EntityCollection GetConnectionRole(IOrganizationService service, string connectionRoleValue)
{
//Retrieve Connection Role Guids...
QueryExpression queryConnectionRole = new QueryExpression("connectionrole")
{
ColumnSet = new ColumnSet("connectionroleid", "name"),
Criteria = new FilterExpression
{
Conditions =
{
new ConditionExpression
{
AttributeName = "name",
Operator = ConditionOperator.Equal,
Values = { connectionRoleValue }
}
}
}
};
EntityCollection connectionResult = service.RetrieveMultiple(queryConnectionRole);
return connectionResult;
}
public void CreateConnection(IOrganizationService service, ITracingService tracingService, IPluginExecutionContext context, Entity entity)
{
try
{
string message = context.MessageName.ToLower();
string amrAccountUser = string.Empty;
if (message == "create")
{
Guid record2Id = ((Microsoft.Xrm.Sdk.EntityReference)(entity.Attributes["record2id"])).Id;
Guid record1Id = ((Microsoft.Xrm.Sdk.EntityReference)(entity.Attributes["record1id"])).Id;
QueryExpression query = new QueryExpression("contact");
EntityCollection Result = null;
var columnNames = new[] { "fullname", "emailaddress1" };
FilterExpression filterExpression = new FilterExpression(LogicalOperator.And);
filterExpression.AddCondition("contactid", ConditionOperator.Equal, record1Id);//record1Id Contact Id that is selected in lookup.
query.ColumnSet.AddColumns(columnNames);
query.Criteria = filterExpression;
query.LinkEntities.Add(new LinkEntity("contact", "account", "parentcustomerid", "accountid", JoinOperator.LeftOuter));
query.LinkEntities[0].Columns.AddColumn("accountid");
query.LinkEntities[0].Columns.AddColumn("accountnumber");
Result = service.RetrieveMultiple(query);
//string associatedAccount = ((AliasedValue)Result.Entities[0]["account1.accountid"]).Value.ToString();//retrive the associated account to the selected contact.
string associatedAccount = "";
if (Result != null && Result.Entities.Any())
{
associatedAccount = ((AliasedValue)Result.Entities[0]["account1.accountid"]).Value.ToString();
}
else
return;
Guid accountid = new Guid(associatedAccount);
//Retrieve the selected connection role..
Entity connectionEntity = new Entity();
var conRoleColumns = new[] { "name" };
ColumnSet connColumns = new ColumnSet(conRoleColumns);
connectionEntity = service.Retrieve("connectionrole", ((Microsoft.Xrm.Sdk.EntityReference)(entity.Attributes["record1roleid"])).Id, connColumns);
string connectionRoleValue = connectionEntity.Attributes["name"].ToString(); //Connection role referenced entity. Role value doesn't exist in Connection so retrieve with additional call.
if (connectionRoleValue == "Testing Locatoin1")
{
connectionRoleValue = "Testing Main Location1";
}
else if (connectionRoleValue == "Test Locatio2")
{
connectionRoleValue = "Testing Main Location2";
}
EntityCollection connectionResult = GetConnectionRole(service, connectionRoleValue);
if (connectionResult == null || !connectionResult.Entities.Any())
return;
Entity connection = new Entity();
connection.LogicalName = "connection";
//Dynamics check to create the connection for Opportunity or Lead based on where the connection is selectd.
if (((Microsoft.Xrm.Sdk.EntityReference)(entity.Attributes["record2id"])).LogicalName == "opportunity")
connection.Attributes.Add("record1id", new EntityReference("opportunity", record2Id));
else if (((Microsoft.Xrm.Sdk.EntityReference)(entity.Attributes["record2id"])).LogicalName == "lead")
connection.Attributes.Add("record1id", new EntityReference("lead", record2Id));
connection.Attributes.Add("record2id", new EntityReference("account", accountid));
connection.Attributes.Add("record2roleid", new EntityReference("connectionrole", new Guid(connectionResult.Entities[0].Attributes["connectionroleid"].ToString())));
service.Create(connection);
}
}
catch (FaultException<OrganizationServiceFault> ex)
{
tracingService.Trace("Error Occurred in Create Connection Plugin: " + ex.Message);
throw new InvalidPluginExecutionException("An error occurred in the Lead Connection Plugin.", ex);
}
catch (Exception ex)
{
tracingService.Trace("Error Occurred in Create Connection Connection :", ex);
throw;
}
}
public static void EnablePlugin(IOrganizationService orgService, bool enable)
{
var messapgeProcessQE = new QueryExpression("sdkmessageprocessingstep");
messapgeProcessQE.ColumnSet.AddColumns("sdkmessageprocessingstepid", "name");
EntityCollection obj = orgService.RetrieveMultiple(messapgeProcessQE);
int pluginStateCode = enable ? 0 : 1;
int pluginStatusCode = enable ? 1 : 2;
//Connection Step
Guid stepId = new Guid("cdcd5b74-ea0c-e811-80f1-3863bb34ecf0");
orgService.Execute(new SetStateRequest
{
EntityMoniker = new EntityReference("sdkmessageprocessingstep", stepId),
State = new OptionSetValue(pluginStateCode),
Status = new OptionSetValue(pluginStatusCode)
});
}
}
}
Hi SVN,
What's the error you are getting? How these plugins are registered, async/ sync, pre/post etc. Did you set the execution order of these plugins?
Create a custom field on the connection entity, populate it from your first plugin, and, in the second plugin, see if that field is in the context Target. If it's there, do nothing in the second plugin. If it's not there, the connection record is being created manually.
Stay up to date on forum activity by subscribing. You can also customize your in-app and email Notification settings across all subscriptions.
André Arnaud de Cal... 291,253 Super User 2024 Season 2
Martin Dráb 230,188 Most Valuable Professional
nmaenpaa 101,156