#c# #crm #microsoft-dynamics
#c# #crm #microsoft-dynamics
Вопрос:
Я работаю над некоторым кодом для считывания основного поля из вложения электронной почты Dynamics CRM и декодирования строки Base64 обратно в файл для записи в файловую систему.
Этот процесс, похоже, отлично работает с файлами изображений, такими как .PNG и т. Д., Excel .xls и т. Д., Но когда я пытаюсь преобразовать файл PDF в массив байтов на C #, я получаю сообщение об ошибке:
Недопустимая длина для массива символов Base-64 или строки в строке Convert.FromBase64String().
var binaryData = File.ReadAllText(@"E:teststream.txt");
byte[] byteArray = Convert.FromBase64String(binaryData);
File.WriteAllBytes(@"E:testfile.pdf", byteArray);
Я пытался сохранить двоичные данные в файле и прочитать их, а также просто определить строку C # с содержимым. Как я уже сказал, это работает с другими типами файлов, но только не с PDF.
Я нашел другую ссылку на ту же проблему, https://social.microsoft.com/Forums/en-US/7a28e106-3715-42b9-a743-9e5207a02540/problem-while-decoding-the-body-field-of-activitymimeattachment-entity?форум =crm
Но решение состояло в том, чтобы просто перебирать байтовый массив и записывать каждый байт по отдельности, он все равно попадает в поврежденный файл PDF, который не открывается в Acrobat.
В конечном счете, я буду считывать двоичные данные из поля базы данных или через CRM API, но я просто хотел сначала проверить теорию, и, похоже, я хорошо разбираюсь во всех типах вложений, кроме PDF…
Комментарии:
1. В одном сообщении, которое я видел, говорилось, что попробуйте заполнить двоичные данные перед преобразованием в байтовый массив .. я попробовал что-то вроде приведенного ниже, и я прошел мимо ошибки преобразования, но PDF-файл по-прежнему поврежден: string DummyData = b.Trim().Replace(» «, » «); if (DummyData. Длина % 4 > 0) DummyData = DummyData.PadRight(DummyData. Длина 4 — DummyData. Длина % 4, ‘=’); byte[] ByteArray = Convert.FromBase64String(DummyData);
2. Работа с байтами и работа с текстом — это совершенно разные задачи в программировании. При преобразовании текста в байты (и наоборот) программа будет форматировать байты на основе предположений о кодировке, порядке байтов и локализации, чтобы назвать несколько примеров. Если это не является абсолютно необходимым для преобразования файла в текст, вы должны обрабатывать файл как массив байтов от начала до конца.
Ответ №1:
Это всего лишь мое предположение, я понятия не имею, работает ли это.
Иногда кодировка символов неверна, потому что текстовые файлы могут иметь спецификацию (метку порядка байтов), и только произвольные двоичные данные могут ей мешать. Вы можете принудительно преобразовать кодировку в ASCII, прочитав данные в двоичном byte[]
формате, а затем преобразовав их в ASCII, как показано здесь:
byte[] data;
data = File.ReadAllBytes(@"E:teststream.txt");
string base64 = System.Text.Encoding.ASCII.GetString(data);
data = Convert.FromBase64String(base64);
File.WriteAllBytes(@"E:testfile.pdf", data);
Давайте посмотрим, решит ли это что-нибудь.
Комментарии:
1. спасибо, я попробовал использовать кодировку ASCII.. в итоге мой исходный поток был плохим для файлов размером более 32 КБ .. поскольку он работал с небольшими файлами, я ошибочно предположил, что моя методология была правильной.. но это было не так.. спасибо за ответ.
Ответ №2:
я узнал, что значение в поле BODY в таблице SQL содержит только 32 КБ потока больших двоичных объектов. я понятия не имею, где находится его сброс. я поспрашивал, и все сказали, что «получение из SQL не поддерживается».. хотя чтение данных из отфильтрованных представлений CRM SQL поддерживается…
итак, когда я тестировал с небольшими файлами PNG и JPG, все было в порядке, но если бы я попробовал файл большего размера, это не сработало бы, я нажал, когда все самые большие потоки были 32 КБ при сохранении в файловой системе.
в конце концов я решил эту проблему, получив данные потока вложений через CRM SDK, а не из SQL в представлении FilteredEmailAttachment в SQL
var attachments = (from a in cc.CRMContext.ActivityMimeAttachments where a.ActivityId == email.ActivityId select a).ToList();
foreach (var attachment in attachments)
{
byte[] byteArray = Convert.FromBase64String(attachment.Body);
System.IO.File.WriteAllBytes(@"E:testtemp" attachment.FileName, byteArray);
}
Ответ №3:
Поскольку это ошибка, возникающая из-за логики проверки, возможно, вы могли бы проверить, есть ли пробелы в данных base64, и если они есть, замените их на ‘ ‘. Копирование сценария проблемы с решением, о котором я говорю.
var binaryData = File.ReadAllText(@"E:teststream.txt");
byte[] byteArray = Convert.FromBase64String(binaryData.Replace(' ', ' '));
File.WriteAllBytes(@"E:testfile.pdf", byteArray);
В прошлом у меня это работало.