Hi All,
I am brand new to CRM and CRM Plugins. I created a c# plugin and registered it on a Create Step. The plugin works great. When I create a record of type A it should create related records of type B. This works great.
Now I want to change the step to create the related B records when A is updated instead of created. I unregistered the step and reregistered the step as an Update message. When I save a recod of type A I get the following error message:
Unexpected exception from plug-in (Execute): PlugIn_ATF_Application_Requirements.PluginATFApplicationRequirements: System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary. If you contact support, please provide the technical details.
My Plugin Code is below and the registration step is below that. Any help would be appreciated!
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using System;
using System.ServiceModel;
namespace PlugIn_ATF_Application_Requirements
{
public class PluginATFApplicationRequirements : IPlugin
{
void IPlugin.Execute( IServiceProvider serviceProvider )
{
// Obtain the tracing service
ITracingService tracingService =
( ITracingService )serviceProvider.GetService( typeof( ITracingService ) );
// Obtain the execution context from the service provider.
IPluginExecutionContext context = ( IPluginExecutionContext )serviceProvider.GetService( typeof( IPluginExecutionContext ) );
// The InputParameters collection contains all the data passed in the message request.
if ( context.InputParameters.Contains( "Target" ) && context.InputParameters["Target"] is Entity )
{
// Obtain the target entity from the input parameters.
Entity entity = ( Entity )context.InputParameters["Target"];
tracingService.Trace( $"Passed in Entity Information. LogicalName: {entity.LogicalName} aws_name: {entity.Attributes["aws_name"]} applicationID: {entity.Id} applicationTypeID: {entity.Attributes["aws_accreditationapplicationtypeid"]}" );
// Obtain the organization service reference which you will need for web service calls.
IOrganizationServiceFactory serviceFactory = ( IOrganizationServiceFactory )serviceProvider.GetService( typeof( IOrganizationServiceFactory ) );
IOrganizationService service = serviceFactory.CreateOrganizationService( context.UserId );
try
{
// Plug-in business logic goes here.
// Findout what object brought us here
Guid accreditationApplicationID = entity.Id;
// Fetch an ATF Appliction record based on the passed in ID and all requirements for the applicationTypeID found on the Application
Entity atfApplication = service.Retrieve( "aws_accreditationapplication", accreditationApplicationID, new ColumnSet( true ) );
tracingService.Trace( $"Found application: {atfApplication.Attributes["aws_name"]}" );
// 2021-09-17 Steven Rieger
// Added check to see if requirements exist already. If so, we are done here. If not, then create them.
// Look for existing requirements for this applicatio
var queryExpression = new QueryExpression()
{
EntityName = "aws_accreditationapplicationrequirement",
// Fetch all columns
ColumnSet = new ColumnSet( true ),
Criteria = new FilterExpression()
{
// Pull the applicationTypeID from the application record
Conditions =
{
new ConditionExpression( "aws_accreditationapplicationid", ConditionOperator.Equal, accreditationApplicationID )
}
}
};
// Do the fetch
EntityCollection receivedRequirements = service.RetrieveMultiple( queryExpression );
if ( receivedRequirements.Entities.Count == 0 )
{
tracingService.Trace( "No Requirements Found. Let's create them!" );
// Fetch the requirements setup for the Application Type ID
queryExpression = new QueryExpression()
{
EntityName = "aws_accreditationrequirement",
// Fetch all columns
ColumnSet = new ColumnSet( true ),
Criteria = new FilterExpression()
{
// Pull the applicationTypeID from the application record
Conditions = { new ConditionExpression( "aws_accreditationapplicationtypeid", ConditionOperator.Equal, ( ( EntityReference )atfApplication["aws_accreditationapplicationtypeid"] ).Id ) }
}
};
// Do the fetch
receivedRequirements = service.RetrieveMultiple( queryExpression ); //"aws_accreditationrequirement", retrievedAccreditationApplication.aws_AccreditationApplicationTypeId.Id, requireMentColumns );
// Loop through all the requirements found and add them to the ATF Application
tracingService.Trace( "Retrieved {0} requirements\n", receivedRequirements.Entities.Count );
foreach ( Entity requirement in receivedRequirements.Entities )
{
tracingService.Trace( $"Processing Requirement {requirement["aws_name"]}\n" );
Guid applicationRequirementID = new Guid();
// Create the new app requirement Entity
Entity applicationRequirement = new Entity( "aws_accreditationapplicationrequirement" );
// Populate the requird fields...
applicationRequirement.Attributes.Add( "aws_accreditationapplicationid", new EntityReference( atfApplication.LogicalName, atfApplication.Id ) );
applicationRequirement.Attributes.Add( "aws_accreditationrequirementid", new EntityReference( requirement.LogicalName, requirement.Id ) );
applicationRequirement.Attributes.Add( "statuscode", 1 );
applicationRequirement.Attributes.Add( "aws_name", requirement.Attributes["aws_name"] );
applicationRequirementID = service.Create( applicationRequirement );
tracingService.Trace( $"Created Requirement: {requirement["aws_name"]}\n" );
}
}
}
catch ( FaultException ex )
{
tracingService.Trace( "PluginATFApplicationRequirements: {0}", ex.ToString() );
throw new InvalidPluginExecutionException( "An error occurred in PluginATFApplicationRequirements.", ex );
}
catch ( Exception ex )
{
tracingService.Trace( "PluginATFApplicationRequirements: {0}", ex.ToString() );
throw;
}
}
}
}
}
2021_2D00_09_2D00_17_5F00_9_2D00_00_2D00_10.pdf
I'm using on prem version 9.x of CRM