Импорт данных приложения Dynamics CRM с помощью SDK

Я пытаюсь импортировать вложения/аннотации в CRM Dynamics, я делаю это с помощью SDK.

Я не использую мастер импорта данных.

Я не создаю сущности аннотаций по отдельности, вместо этого я использую Функция импорта данных программно.

В основном я использовал пример DataImport из примера кода SDK (SDK\SampleCode\CS\DataManagement\DataImport).

     Import import = new Import()
            {
                ModeCode = new OptionSetValue((int)ImportModeCode.Create),
                Name = "Data Import"
            };
 Guid importId = _serviceProxy.Create(import);


_serviceProxy.Create(
                   new ColumnMapping()
                   {
                       ImportMapId = new EntityReference(ImportMap.EntityLogicalName, importMapId),
                       ProcessCode = new OptionSetValue((int)ColumnMappingProcessCode.Process),

                       SourceEntityName = sourceEntityName,
                       SourceAttributeName = sourceAttributeName,

                       TargetEntityName = targetEntityName,
                       TargetAttributeName = targetAttributeName

                   });

Выдает ошибку "Ссылка на вложение не найдена".

В документации говорится, что асинхронная служба crm найдите физический файл на диске и загрузите его, мой вопрос: где асинхронная служба ищет вложенные файлы?

Я попытался сопоставить поле документа с полным путем к вложению на столе, но это все равно не сработало.


person Socardo    schedule 01.08.2016    source источник


Ответы (2)


Ответ ниже был предоставлен до редактирования вопроса, разъясняющего использование мастера импорта вместо SDK. Ответ ниже относится к использованию SDK.


Когда вы прикрепляете файлы к записи аннотации (примечания) в CRM через SDK, вы используете атрибут documentbody (наряду с mimetype), но сначала вам нужно преобразовать его в base64.

Что-то вроде этого:

var myFile = @"C:\Path\To\My\File.pdf";
// Do checks to make sure file exists...

// Convert to Base64.
var base64Data = Convert.ToBase64String(System.IO.File.ReadAllBytes(myFile));

var newNote = new Entity("annotation");

// Set subject, regarding object, etc.

// Add the data required for a file attachment.
newNote.Attributes.Add("documentbody", base64Data);
newNote.Attributes.Add("mimetype", "text/plain"); // This mime type seems to work for all file types.

orgService.Create(newNote);
person Jason Faulkner    schedule 01.08.2016
comment
Спасибо и извините, я не понял, я использую функцию DataImport. Я обновил свой вопрос, чтобы добавить больше деталей. - person Socardo; 01.08.2016
comment
После прочтения ваших правок асинхронная служба, скорее всего, будет смотреть только на сам сервер — у нее не будет доступа к рабочему столу клиента (при условии, что это то, что вы имеете в виду, когда говорите «стол»). Я никогда не возился с мастером импорта для импорта вложений — я просто всегда использовал SDK. - person Jason Faulkner; 01.08.2016
comment
Мой код работает на сервере, вложения находятся на сервере, просто не знаю, где асинхронная служба ищет файлы, если она ищет в первую очередь, документации очень не хватает. - person Socardo; 01.08.2016
comment
На данный момент я размышляю (опять же, я импортировал вложения только через SDK), но если все находится на сервере, проверьте разрешения для каталога/файлов, которые вы пытаетесь загрузить. Какой бы пользователь ни работал в пуле приложений CRM IIS, он должен иметь доступ к указанному вами пути. - person Jason Faulkner; 01.08.2016
comment
Я понял, как это должно работать, я не думаю, что файлы могут быть доступны на сервере, я думаю, что документация неясна в этом отношении, пожалуйста, проверьте мой ответ. Спасибо! - person Socardo; 01.08.2016

Я нашел решение в малоизвестном блоге post, я думаю, что документация вводит в заблуждение или неясна, то, как все это работает, делает наличие файлов на диске сервера доступным для асинхронной обработки странным.

Чтобы следовать тому же принципу, все содержимое должно быть отправлено так же, как и сам CSV-файл, при этом оно должно быть связано с одним и тем же импортом.

Чтобы решить эту проблему, нам нужно создать отдельный специальный Internal ImportFile для каждого физического вложения и связать его с импортом, в котором есть сведения о записи вложений.

Как вы видите ниже, при связывании вложений ImportFile с помощью ImportId и последующей установке двух свойств (ProcessCode и FileTypeCode) все в итоге заработало.

Достаточно сказать, что использование этого метода намного эффективнее и быстрее, чем индивидуальное создание записей аннотаций.

foreach (var line in File.ReadLines(csvFilesPath + "Attachment.csv").Skip(1))
            {
                var fileName = line.Split(',')[0].Replace("\"", null);
                using (FileStream stream = File.OpenRead(attachmentsPath + fileName))
                {
                    byte[] byteData = new byte[stream.Length];
                    stream.Read(byteData, 0, byteData.Length);
                    stream.Close();
                    string encodedAttachmentData = System.Convert.ToBase64String(byteData);

                    ImportFile importFileAttachment = new ImportFile()
                    {
                        Content = encodedAttachmentData,
                        Name = fileName,
                        ImportMapId = new EntityReference(ImportMap.EntityLogicalName, importMapId),
                        UseSystemMap = true,
                        ImportId = new EntityReference(Import.EntityLogicalName, importId),
                        ProcessCode = new OptionSetValue((int)ImportFileProcessCode.Internal),
                        FileTypeCode = new OptionSetValue((int)ImportFileFileTypeCode.Attachment),
                        RecordsOwnerId = currentUserRef
                    };
                    _serviceProxy.Create(importFileAttachment);
                }
                idx++;
            }
person Socardo    schedule 01.08.2016