Hi,
I am running into a strange issue and trying to figure out a solution. We need to create a connection based on certain logic. Create a connection to the associated account of a contact based on the selected role for that contact. In below code if the user select a contact entity and a role in the connection sub-grid form i am trying to find the associated account and create a connection with a different role. I have created the plug-in and registered it on Connection entity for create. I am getting below error at the time of creating the connection but if i debug the plug-in it works fine (when i selected the debug option persist to entity). When i debug that particular profile it creates the connection. As soon as i remove the profile it throws below error.
I also debugged by selecting the profile to capture when an error occurred. In this cases the recor1id that i used in code is being switched to opportunity and record2id is switched to contact. Also i couldn't find the record1roleid but i can record2roleid and it throws the error.
1. Not sure what is wrong in the code that i implemented.
2. Why i am getting the error i dont think i have missed any condition at the time of reading the elements. I have mentioned the code snippet here following the error message.
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.
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.
//Change the role value as per the requirement.
if (connectionRoleValue == "Stake Holder")
{
connectionRoleValue = "Stake Holder Office";
}
else if (connectionRoleValue == "Employee")
{
connectionRoleValue = "Employee Office";
}
//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 = null;
connectionResult = service.RetrieveMultiple(queryConnectionRole);
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;
}
}
Error Details::
Error Occurred in Create Lead Connection Plugin: Unexpected exception from plug-in (Execute): LeadConnection.LeadConnection: System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index
Can some one verify and suggest what am i doing wrong.
Note: I tested by registering Asynchronous as well just to avoid the exception details to the user. It creates the connection but in plug-in trace log i can see 4 entries. 2 for successful entry and 2 for error out record. It seems its trying to make a call that i am unable to figure. Appreciate if any one can provide share some thoughts on this.