How to Import attachments programmatically

I recently came across a query where a customer was having trouble in using the import SDK APIs to import attachment records in CRM. So I thought of writing this blog which explains the steps required to import attachment files in CRM using auto mapping feature of CRM import SDK and its APIs along with some sample code. One can also specify an import map but in this blog I’ll cover auto map feature only to keep things simple.


On a high level the steps are as follows:

  1. Create a CSV file containing the details of attachments that you want to import.
  2. Create the root import record
  3. Create import file record for attachments which contains actual attachment file contents.
  4. Create import file record which contains mapping for attachments records.
  5. Call import SDK APIs.

Let’s go through these steps one by one with sample code.

1. Create a CSV file containing the details of attachments that you want to import.

First create an in memory csv file which contains the details of attachments that you want to import. You can also use an already created csv file and read its contents from the disk but to keep things simple I am creating it in memory. In order to
use the auto mapping feature of import the first row of csv should contain the display names of the attributes from target import entity. The rows that will follow the first row will contain actual data which should be imported in those attributes of the target entity.

In the following code sample the first row contains the comma separated display names of attributes from annotation entity followed by the data which should be there in those columns. The annotation is a special case in import hence the data for “Document” columns contains
the file name instead of actual content. I’ll show in next steps where the actual content needs to be specified.

2.      Create the root import record.

This is the root import record which binds the different import files which need to be imported together. You can see this record in the “Imports” navigation area in the mail application.


3.      Create import file record for attachments which contains actual file contents.

Now you need to create an import file record where actual contents on the attachment are saved. This can be done using following code.


4.      Create import file record which contains mapping for attachments.

Now create another import file record which contains the data that we created in step to import annotations in CRM.

 5.      Call actual import SDK APIs

Once all record are in place we are ready to actually do the import work. Import SDK provides the Parse, transform and Import SDK APIs for this work. Note that these APIs submits asynchronous jobs to do the actual import work.

The unique id of asynchronous job is returned by these APIs. You can monitor the status of these jobs using the ids which are returned by these APIS.

Once all three jobs are completed your data should get imported into the system. You can check it in the opening the import job record in the application.

Following code shows how these APIs can be called.



For more information, see:

Import Data in Microsoft Dynamics CRM

Data Import Entities

Sample: Import Data Using Complex Data Map

- Huma Ramawat


Comments (1)

  1. The sample code in above blog is in image format. Hence pasting the code here for ease of use. Please ping leave a reply if you find some error in the code.

          /// <summary>

           /// Impport attachments in CRM

           /// </summary>

           public void ImportAttachmentRecords()


    OrganizationServiceProxy _serviceProxy; // Initialize the _serviceProxy appropriately.

               // 1. Create a CSV file containing the details of attachments that you want to import.

               string fileName = DateTime.UtcNow.Ticks + ".txt";

               string attachmentContent = "This is the attachment content"; // Put your attachment contents here.

               string attachmentData = Convert.ToBase64String(Encoding.UTF8.GetBytes(attachmentContent));

               StringBuilder sb = new StringBuilder();

               //Add header row

               sb.AppendLine("Title, Document, File Name, Regarding");

               string accountId = "04AFD3BF-16D6-E111-A43C-00155D187A0A"; // This is the unique id of CRM record e.g. account with which you want to attach this note.

               string dataRow = "attachment1, " + fileName + ", " + fileName + "," + accountId;


               string csvData = sb.ToString();

               // 2.    Create the root import record

               Import import = new Import()


                   ModeCode = new OptionSetValue((int)ImportModeCode.Create),

                   Name = "Importing data"


               Guid importId = _serviceProxy.Create(import);

              // 3.    Create import file record for attachments which contains actual file contents.

               ImportFile importAttachmentFile = new ImportFile()


                   Content = attachmentData, // Read contents from disk.

                   Name = fileName,

                   UseSystemMap = true,

                   ImportId = new EntityReference(Import.EntityLogicalName, importId),

                   ProcessCode =

                       new OptionSetValue((int)ImportFileProcessCode.Internal),

                   FileTypeCode = new OptionSetValue(2)


               Guid importAttachmentFileId = _serviceProxy.Create(importAttachmentFile);

               // 4.    Create import file record which contains mapping for attachments.

               ImportFile importFile = new ImportFile()


                   Content = csvData, // Read contents from disk.

                   Name = "Attachment Import File",

                   IsFirstRowHeader = true,

                   UseSystemMap = true,

                   Source = "Import Attachment",

                   SourceEntityName = "attachment",

                   TargetEntityName = Annotation.EntityLogicalName,

                   ImportId = new EntityReference(Import.EntityLogicalName, importId),

                   EnableDuplicateDetection = false,

                   FieldDelimiterCode =

                       new OptionSetValue((int)ImportFileFieldDelimiterCode.Comma),

                   DataDelimiterCode =

                       new OptionSetValue((int)ImportFileDataDelimiterCode.DoubleQuote),

                   ProcessCode =

                       new OptionSetValue((int)ImportFileProcessCode.Process)


               Guid importFileId = _serviceProxy.Create(importFile);

               // 5.    Call import SDK APIs

               // Parse the import file.

               ParseImportRequest parseImportRequest = new ParseImportRequest()


                   ImportId = importId


               ParseImportResponse parseImportResponse =


               WaitForAsyncJobCompletion(_serviceProxy, parseImportResponse.AsyncOperationId);

               // Transform the import

               TransformImportRequest transformImportRequest = new TransformImportRequest()


                   ImportId = importId


               TransformImportResponse transformImportResponse =


               WaitForAsyncJobCompletion(_serviceProxy, transformImportResponse.AsyncOperationId);

               // Upload the records.

               ImportRecordsImportRequest importRequest = new ImportRecordsImportRequest()


                   ImportId = importId


               ImportRecordsImportResponse importResponse =


               WaitForAsyncJobCompletion(_serviceProxy, importResponse.AsyncOperationId);


           /// <summary>

           /// Waits for the async job to complete.

           /// </summary>

           /// <param name="asyncJobId"></param>

           public void WaitForAsyncJobCompletion(OrganizationServiceProxy serviceProxy, Guid asyncJobId)


               ColumnSet cs = new ColumnSet("statecode", "statuscode");

               AsyncOperation asyncjob =

                   (AsyncOperation)serviceProxy.Retrieve("asyncoperation", asyncJobId, cs);

               int retryCount = 100;

               while (asyncjob.StateCode.Value != AsyncOperationState.Completed && retryCount > 0)


                   asyncjob = (AsyncOperation)serviceProxy.Retrieve("asyncoperation", asyncJobId, cs);





Skip to main content