CRM Plugin Did not Update All Fields

473 Views Asked by At

We're on CRM 2016 On-Premise. I have registered a plugin that gets triggered when two fields are being updated: fieldA and fieldB. The plugin will encrypt both fields, but for some reason it would only update the first field: fieldA

We registered the plugin as Post-Operation. We also registered a PostImage with both fieldA and fieldB as the filter. However for some reason it would only update fieldA and not fieldB.

Here's my code. I put a 'throw new InvalidPluginExecutionException' after the assignment of fieldB, but for some reason it is never reached. If I put InvalidPluginExecutionException BEFORE the assignment of fieldB (but still inside the if condition), then I would receive the error message.

I am not sure what is wrong with the assignment...

        string fieldA;
        string fieldB;

        var targetEntity = context.GetParameterCollection<Entity>(context.InputParameters, "Target");

        if (targetEntity == null)
            throw new InvalidPluginExecutionException(OperationStatus.Failed, "Target Entity cannot be null");

        var serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
        var service = serviceFactory.CreateOrganizationService(context.UserId);

        if (context.Depth == 1)
        {
            var postImage = context.PostEntityImages["PostImage"];

            if (postImage == null)
                throw new InvalidPluginExecutionException(OperationStatus.Failed, "Post Image is required");

            var account = context.GenerateCompositeEntity(targetEntity, postImage);

            if (targetEntity.Attributes.Contains("new_fieldA"))
            {
                fieldA = account.Attributes["new_fieldA"].ToString();
                targetEntity["new_fieldA"] = encrypt(fieldA);
            }

            if (targetEntity.Attributes.Contains("new_fieldB"))
            {
                fieldB = account.Attributes["new_fieldB"].ToString();
                throw new InvalidPluginExecutionException("test222"); //for some reason this message never shows up
                //targetEntity["new_fieldB"] = encrypt(fieldB);
                //targetEntity["new_fieldB"] = "hello";
            }

            service.Update(targetEntity);
1

There are 1 best solutions below

0
Henk van Boeijen On

I see two possible causes here for your plugin to fail:

  • context.GenerateCompositeEntity(targetEntity, postImage) may introduce unexpected effects.
  • Attribute name "new_fieldB" may be misspelled.

Whatever it is, you could simplify your plugin considerably by registering it for the pre operation create and update stages. In those stages you can modify your fields on the fly and you do not need to update the entity separately.

E.g. this is all you need:

var targetEntity = (Entity)context.InputParameters["Target"];

void Encrypt(string attributeName)
{
    if (targetEntity.Attributes.Contains(attributeName))
        entity[attributeName] = encrypt(targetEntity.GetAttributeValue<string>(attributeName));
};

Encrypt("new_fieldA");
Encrypt("new_fieldB");

Some explanation:

  • It is not necessary to check if "Target" is in the InputParameters collection. If it is not, you did not register your plugin on the create or update messages.
  • A pre or postimage is not needed. When your field is modified, all you need is its new value in the entity's target version.
  • No check is needed on Depth, since your plugin does not update the same record again.
  • This code sample can be used for both the create and the update messages. No changes needed.
  • Using one function for processing an attribute will pretty much narrow down the number of possibilities making a mistake here.