Pass parameters into a plugin

Let’s suppose we have a Web API making some calls to the Dynamics CRM, in order to retrieve some entity records, and there are plugins running against the Retrieve Multiple message in post-operation stage. The business logic which is implemented in the retrieve multiple plugin should only be executed if the retrieve multiple is made from the Web API, and when is triggered from other sources other than the Web API, the logic should not be executed. This is a challenge I have faced recently.

The first thing I thought, would be, somehow, trying to pass a parameter into the plugin in order to signal when the retrieve multiple is made from the Web API.

The idea I came up with was:

  • Web API: Add a filter condition in the query expression being performed (I was using query expression, the same is valid for Fetch Expression where the custom parameter could be passed in the fetch xml header) which contained the key and its value to pass into the plugin;

retrieve_multiple

  • Pre-operation (Retrieve Multiple): In order to avoid the query expression to fault, due to the condition previously added, it is necessary to remove that condition in the pre-operation stage of the retrieve multiple. Therefore in this stage, the filter condition is accessed, obtained the key and the value, and remove the filter condition from the query expression. As the parameter is needed in the post-operation stage, then it is added to the shared variables;

retrieve_multiple_2

  • Post-operation (Retrieve Multiple): The parameter is obtained from the shared variables.

retrieve_multiple_3

This same principle may be applied to other messages, like create or update where the custom parameters can be passed into the plugin through the target attributes collection (like next figure), being removed in the pre-operation.

retrieve_multiple_4

Advertisements

6 Comments

  1. It’s not working for the Create message if entity metadata doesn’t contain attribute with the same name. CRM throws exception that attribute was not found in metadata. I tested for the Create request. What will Nuno say to me?

    Exception detail:
    contact’ entity doesn’t contain attribute with Name = ‘new_disableattribute’ and NameMapping = ‘Logical’.

    code: “0x80040265″
    stacktrace: ” at Microsoft.Crm.Extensibility.OrganizationSdkServiceInternal.Execute(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType, Boolean checkAdminMode, ExecutionContext executionContext)
    at Microsoft.Crm.Extensibility.OData.CrmODataExecutionContext.Upsert(Entity entity)
    at Microsoft.Crm.Extensibility.OData.CrmODataExecutionContext.Update(Entity entity, UpdateOption updateOption)
    at Microsoft.Crm.Extensibility.OData.CrmODataServiceDataProvider.UpdateEdmEntity(CrmODataExecutionContext context, String edmEntityName, String entityKeyValue, EdmEntityObject entityObject)
    at Microsoft.Crm.Extensibility.OData.EntityController.PatchEntityImplementation(String& entityName, String key, EdmEntityObject entityDelta)
    at Microsoft.PowerApps.CoreFramework.ActivityLoggerExtensions.Execute[TResult](ILogger logger, EventId eventId, ActivityType activityType, Func`1 func)
    at Microsoft.Xrm.Telemetry.XrmTelemetryExtensions.Execute[TResult](ILogger logger, XrmTelemetryActivityType activityType, Func`1 func)
    at lambda_method(Closure , Object , Object[] )
    at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.c__DisplayClass10.b__9(Object instance, Object[] methodParameters)
    at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)
    — End of stack trace from previous location where exception was thrown —
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
    at System.Web.Http.Controllers.ApiControllerActionInvoker.d__0.MoveNext()
    — End of stack trace from previous location where exception was thrown —
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
    at System.Web.Http.Controllers.ActionFilterResult.d__2.MoveNext()
    — End of stack trace from previous location where exception was thrown —
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
    at System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()”
    type: “System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=9.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]”

    Like

  2. Hi Dima,

    For this to work on create operation it is necessary to remove the custom attribute from the target attributes collection in the pre-operation, otherwise you’ll get that error because the custom attribute is not an entity field.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s