web
You’re offline. This is a read only version of the page.
close
Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Microsoft Dynamics CRM (Archived)

Create Connection Dynamically with plug-in throws an error.

(0) ShareShare
ReportReport
Posted on by 397

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.

*This post is locked for comments

I have the same question (0)
  • Suggested answer
    Michel Gueli Profile Picture
    982 on at

    Check these two lines:

    Result = service.RetrieveMultiple(query);

    string associatedAccount = ((AliasedValue)Result.Entities[0]["account1.accountid"]).Value.ToString();

     

    Why not do a check if the result has any entities?

    if(result != null && result.Entities.Any()) {

    string associatedAccount = ((AliasedValue)Result.Entities[0]["account1.accountid"]).Value.ToString();

    }

  • Suggested answer
    Michel Gueli Profile Picture
    982 on at

    I refreshed you code. Maybe that will help:

    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;

    var contact = service.Retrieve("contact", record1Id, new ColumnSet("parentcustomerid"));

    if (contact.Contains("parentcustomerid"))

    {

    var accountId = contact.GetAttributeValue<EntityReference>("parentcustomerid").Id;

    //Retrieve the selected connection role..

    var connectionRole = service.Retrieve("connectionrole", ((Microsoft.Xrm.Sdk.EntityReference)(entity.Attributes["record1roleid"])).Id, new ColumnSet("name"));

    if (connectionRole.Contains("name"))

    {

    string connectionRoleValue = connectionRole.GetAttributeValue<string>("name"); //Connection role referenced entity. Role value doesn't exist in Connection so retrieve with additional call.

    if (connectionRoleValue == "Stake Holder")

    {

    connectionRoleValue = "Stake Holder Office";

    }

    else if (connectionRoleValue == "Employee")

    {

    connectionRoleValue = "Employee Office";

    }

    var retrievedConnectionRole = RetrieveConnectionRoleByName(service, connectionRoleValue);

    if (retrievedConnectionRole != null)

    {

    var connection = new Entity("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", retrievedConnectionRole.Id));

    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;

    }

    }

    private Entity RetrieveConnectionRoleByName(IOrganizationService service, string name)

    {

    var query = new QueryExpression("connectionrole");

    query.ColumnSet.AddColumn("name");

    query.Criteria.AddCondition("name", ConditionOperator.Equal, name);

    var result = service.RetrieveMultiple(query);

    if (result != null && result.Entities.Any())

    return result.Entities.First();

    return null;

    }

  • Verified answer
    Srini20 Profile Picture
    397 on at

    Thank you. This seems working but i am still running my cases. I couldn't figure out why that is getting error out because the test data that i took contains the valid references and contains data for that contact & account.

    I left this for negative cases but unable to determine where and why exactly this is failing after creating a successful connection.

  • gdas Profile Picture
    50,091 Moderator on at

    Hi,

    Which line of code you are getting error? Can you debug the plugin and specify which line you are getting error.

  • Srini20 Profile Picture
    397 on at

    Thats the kicker, when i debug it runs fine. If i remove the debugger its getting error out after service.Create(connection);

    As Michel suggested this f(result != null && result.Entities.Any())  line resolved but the debugger never goes in it and the data i took shouldn't fall in this category. This is happening after the successful connection creation. I tested in asynchronous mode, the connection gets created and throws an error too.

  • Michel Gueli Profile Picture
    982 on at

    This is also a tricky part:

    Guid record2Id = ((Microsoft.Xrm.Sdk.EntityReference)(entity.Attributes["record2id"])).Id;

    Guid record1Id = ((Microsoft.Xrm.Sdk.EntityReference)(entity.Attributes["record1id"])).Id;

    var contact = service.Retrieve("contact", record1Id, new ColumnSet("parentcustomerid"));

    Because de ID of record 1 could also be another entity.

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

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Neeraj Kumar – Community Spotlight

We are honored to recognize Neeraj Kumar as our Community Spotlight honoree for…

Leaderboard > 🔒一 Microsoft Dynamics CRM (Archived)

#1
SA-08121319-0 Profile Picture

SA-08121319-0 4

#1
Calum MacFarlane Profile Picture

Calum MacFarlane 4

#3
Alex Fun Wei Jie Profile Picture

Alex Fun Wei Jie 2

Last 30 days Overall leaderboard

Featured topics

Product updates

Dynamics 365 release plans