Syncing Email Attachments
Dynamics 365 stores email attachments in the activitymimeattachment entity, linked to the parent email record via the ObjectID.
This means they can't be synced directly through a standard sync project and instead, Project Automation is used to intercept each new row and create the attachment record manually via the Dynamics SDK.
The code uses the BeforeAddItem event, which fires before Data Sync would normally write each row to the target. Setting item.Sync = false at the start cancels the default sync operation, handing full control to the code below it.
public override void BeforeAddItem(object sender, DataCompareItemInvariant item, object identity)
{
item.Sync = false; // Disable Data Sync
var data = item.ToAddItemDictionary(TargetMapping);
var attachment = new Microsoft.Xrm.Sdk.Entity("activitymimeattachment");
attachment["subject"] = data["subject"];
attachment["filename"] = data["filename"];
attachment["mimetype"] = data["mimetype"];
attachment["body"] = data["body"];
attachment["objectid"] = new Microsoft.Xrm.Sdk.EntityReference("email", (Guid)data["objectid"]);
attachment["objecttypecode"] = "email";
var service = DataSourceB.ExecuteOrganizationRequest(new Microsoft.Xrm.Sdk.Messages.CreateRequest() { Target = attachment});
}
item.ToAddItemDictionary(TargetMapping) converts the incoming row into a dictionary of field values based on the schema map, so you can reference each column by name. A new activitymimeattachment record is then constructed and its fields populated from the source data:
| Field | Description |
|---|---|
| subject | The attachment subject line |
| filename | The filename including extension e.g. Sample.pdf |
| mimetype | The MIME type of the file e.g. application/pdf |
| body | The file content as a base64 encoded string |
| objectid | An EntityReference pointing to the parent email record by Guid |
| objecttypecode | The type of the parent record — email in this case |
Dynamics 365 requires the body field to be a base64 encoded string. Ensure your source data is already base64 encoded before it reaches this step, or convert it here using Convert.ToBase64String() before assigning it to the entity.
Finally, DataSourceB.ExecuteOrganizationRequest() sends a CreateRequest to Dynamics to create the attachment record, which is the Project Automation equivalent of calling service.Create() directly via the Dynamics SDK.