DawidPotgieter / Dynamics-CRM-Binary-Storage-Options

A Dynamics CRM plugin to transparently store attachment binaries outside CRM database. Azure Blob or File storage for instance.
GNU Affero General Public License v3.0
34 stars 15 forks source link

failed to 'Retrieve' for 'activitymimeattachment'. #21

Closed perry513 closed 4 years ago

perry513 commented 5 years ago

After upgrading CRM from v8 to v9.0.3.7, we are receiving below error when downloading email attachment (note attachment is fine)

Below is the error from event viewer The Web Service plug-in failed in OrganizationId: xxx; SdkMessageProcessingStepId: xxx; EntityName: activitymimeattachment; Stage: 30; MessageName: Retrieve; AssemblyName: Microsoft.Crm.Extensibility.InternalOperationPlugin, Microsoft.Crm.ObjectModel, Version=9.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35; ClassName: Microsoft.Crm.Extensibility.InternalOperationPlugin; Exception: Unhandled Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at System.Web.Services.Protocols.LogicalMethodInfo.Invoke(Object target, Object[] values) at Microsoft.Crm.Extensibility.InternalOperationPlugin.Execute(IServiceProvider serviceProvider) at Microsoft.Crm.Extensibility.V5PluginProxyStep.ExecuteInternal(PipelineExecutionContext context) at Microsoft.Crm.Extensibility.VersionedPluginProxyStepBase.Execute(PipelineExecutionContext context) Inner Exception: System.ArgumentOutOfRangeException: Index and length must refer to a location within the string. Parameter name: length at System.String.Substring(Int32 startIndex, Int32 length) at Microsoft.Crm.ObjectModel.AttachmentServiceBase.ExtractEFSFileId(String body) at Microsoft.Crm.ObjectModel.ActivityMimeAttachmentService.<>c__DisplayClass10_0.<Retrieve>b__0() at Microsoft.PowerApps.CoreFramework.ActivityLoggerExtensions.Execute[TResult](ILogger logger, EventId eventId, ActivityType activityType, Func1 func) at Microsoft.Xrm.Telemetry.XrmTelemetryExtensions.Execute[TResult](ILogger logger, XrmTelemetryActivityType activityType, Func1 func)

I tested it from the code and can confirm that _serviceProxy.RetrieveMultiple works. It is just _serviceProxy.Retrieve() gives above error.

We tried to reinstall your CRM solution, which didn't resolve the issue.

Can anyone please help?

Thanks in advance Perry Ma

DawidPotgieter commented 5 years ago

Hi Perry,

Looking at the exception message, I cannot see that this is actually happening within the BSO plugin. The fact that there is an "ExtractEFSFileId" reference in there seems to be indicating something about "Encrypted File System" maybe? Do you perhaps have some other plugins that could be causing this?

The absolute best way to figure this out is to actually debug the "Retrieve" method of the plugin, using the SDK's "Plugin Registration Tool". It allows you to capture a profile of the event you're trying to execute and then replay it by attaching VS debugger using the code.

It is kind of odd though, since if you look at the code, "Retrieve" and "RetrieveMultiple" is basically handled by the exact same code.

Can you check whether the specific file you're trying to access might have originated from an encrypted file system perhaps?

Hmm. Another thing I see is that you retrieve it via the code. Can't be certain exactly what you're trying to do, but have you done this bit : https://github.com/DawidPotgieter/Dynamics-CRM-Binary-Storage-Options/wiki/Caveats#using-iorganizationserviceloadproperty-api ?

Dawid

perry513 commented 5 years ago

Thanks for the quick response, will definitely try to debug it as you suggested and post the result here. Although I suspect the error happens before it reaches the plugin...

It may have something to do with the Encryption, we had some issue with the encryption key during the upgrade. I will check with my college.

Can you check whether the specific file you're trying to access might have originated from an encrypted file system perhaps? No, it happens to all email attachments. We also turned of all compression and encryption in the plugin.

Maybe I should've mentioned that, if I change the "Create of activity mime attachment" to Sync. We then do not receive above error from downloading attachment. I know that it has to be async otherwise the file would not be removed from the database. However, this tells me that, as long as the file is saved in DB, we do not receive above error. I'm not 100% sure but I think in this example, the file is still retrieved from blob but not from DB.

Another thing I see is that you retrieve it via the code No, I'm not retrieving from code. It was only my test app to prove it only happens to retrieve but not retrieve multiple.

perry513 commented 5 years ago

Ok, I can confirm that error is not coming from the plugin. These are the steps I've done

  1. enable profiling for step "Retrieve of activitymimeattachment"
  2. click download on an attachment and received the error
  3. download and debug the profile
  4. no error, I step through and also trace log the entity which looks fine.

It is still an issue with retrieve method, below i have 2 query basically retrieving the same record. `//failed, soon as I retrieve "body" column, note that below retrieve() doesn't trigger a new profile var e = _serviceProxy.Retrieve(ActivityMimeAttachment.EntityLogicalName, new Guid("8e240f9f-9b6f-e911-80d8-00155d6e7301"), new ColumnSet(true) );

                //success
                QueryExpression aq = new QueryExpression
                {
                    EntityName = ActivityMimeAttachment.EntityLogicalName,
                    ColumnSet = new ColumnSet("body"),
                    Criteria = new FilterExpression
                    {
                        Conditions =
                                        {
                                            new ConditionExpression
                                            {
                                                AttributeName = "activitymimeattachmentid",
                                                Operator = ConditionOperator.Equal,
                                                Values = {new Guid("8e240f9f-9b6f-e911-80d8-00155d6e7301") }
                                            }
                                        }
                    }
                };
                EntityCollection rs = _serviceProxy.RetrieveMultiple(aq);`

Looking at the exception message, I cannot see that this is actually happening within the BSO plugin. The fact that there is an "ExtractEFSFileId" reference in there seems to be indicating something about "Encrypted File System" maybe? Do you perhaps have some other plugins that could be causing this?

I checked with college, they couldn't get the old key work during the upgrade + migration. They end up deleting the sensitive data (only 1 record) from DB directly and re-assign a new key. I'm not sure if that breaks anything. edit: no, we dont have any other plugin that relates to email attachment.

I'm pretty lost at the moment on what should I do next. Any help or direction is much appreciated. Maybe I should log a support case with MS.

edit 2: https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/field-level-data-encryption, according to this nothing on attachment table is encrypted.

perry513 commented 4 years ago

Issue has been resolved after CRM is upgraded to v9.0.10.11 (on prem).

DawidPotgieter commented 4 years ago

I would just like to thank you for actually coming back and resolving the issue. Doesn't happen often :)

Cheers.