Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Finance | Project Operations, Human Resources, ...
Answered

Convert PDF file attachment to Base64 string using X++

(1) ShareShare
ReportReport
Posted on by 752
Hi everyone,

I am trying to convert PDF attachment of Sales order invoice into Base64 string.

Below is my code snippet and I referred below blog for same,
https://www.linkedin.com/pulse/get-document-management-attached-file-api-integration-khan/

I converted same file to Base64 using below 2 ways
 
2. Added attachment on Sales order of D365 CRM in notes section. Navigated to Notes table in Dataverse and checked the value in documentbody field
 
In bot cases above, I was able to see same value.
 
My requirement is, to push D365 F&O attachment to D365 CRM sales order attachment. And for same I want Base64 string so that I can populate it in Notes table

However, I am getting some different value in fileBase64Str variable.

let me know how it can be fixed. if any other alternative way I can opt for?
 
internal final class ITSGetAttachedFileRunnabl{    /// <summary>    /// Class entry point. The system will call this method when a designated menu     /// is selected or when execution starts and this class is set as the startup class.    /// </summary>    /// <param name = /_args/>The specified arguments.</param>    public static void main(Args _args)    {        DocuRef docuref;        ITSGetFileFromDocMgmtInVariousFormats runnable = ITSGetFileFromDocMgmtInVariousFormats::construct();        select docuref            where docuref.RecId == 68719599267;        runnable.readfromDocuRefAttachments(docuref);    }}
using Microsoft.Dynamics.ApplicationPlatform.Services.Instrumentation;using Microsoft.DynamicsOnline.Infrastructure.Components.SharedServiceUnitStorage;using Microsoft.Dynamics.AX.Framework.FileManagement;using Microsoft.WindowsAzure.Storage;Using Microsoft.WindowsAzure.Storage.Blob;internal final class ITSGetFileFromDocMgmtInVariousFormats{    str docfiletype;    Microsoft.Dynamics.AX.Framework.FileManagement.IDocumentStorageProvider storageProvider;    Public void readfromDocuRefAttachments(DocuRef _docuRef)    {        Blobdata blobContainer;        AsciiStreamIo file;        container record;        str downloadUrl;        // Grant clrinterop permission.        new InteropPermission(InteropKind::ClrInterop).assert();        if (_docuRef.isValueAttached())        {            var docuValueloc = _docuRef.docuValue();            downloadUrl = docuValueloc.Path;            if (!downloadUrl || docuValueloc.Type == DocuValueType::Others)            {                str accessToken = DocumentManagement::createAccessToken(_docuRef);                downloadUrl = Microsoft.Dynamics.AX.Framework.FileManagement.URLBuilderUtilities::GetDownloadUrl(docuValueloc.FileId, accessToken);            }            storageProvider = Docu::GetStorageProvider(_docuRef.docuType(), false);            var docContents = storageProvider.GetFile(docuValueloc.createLocation());            file = AsciiStreamIo::constructForRead(docContents.Content);            // download file on browser            file.read();            str displayUrl = DocumentManagement::getAttachmentPublicUrl(_docuref);            Browser br = new Browser();            br.navigate(displayUrl);            // To byte - working            System.IO.StreamReader streamReader = new System.IO.StreamReader(docContents.Content);            System.Byte[] bytes;            System.Text.Encoding getUTF8 = System.Text.Encoding::get_UTF8();            //bytes = getUTF8.GetBytes(streamReader.ReadToEnd());            bytes = getUTF8.GetBytes(streamReader.ReadToEnd());            //info ('Byte ready');            // To memorystream            System.IO.MemoryStream stream = new System.IO.MemoryStream(bytes);            //info ('stream ready');            // to binary and blob container            Binary binaryData = Binary::constructFromMemoryStream(stream);            //info ('binary ready');            if (binaryData)            {                blobContainer = binaryData.getContainer();                //info ('Container ready');            }                        // to base 64            str fileBase64Str = con2base64str(blobContainer);            info (strFmt('base: %1', fileBase64Str));            //info (/Base64 ready/);            DocuValue docuValue;            select firstonly docuValue                where docuValue.RecId == _docuRef.ValueRecId;            info (strFmt('Original filename is %1', docuValue.originalFileName));        }    }    public static ITSGetFileFromDocMgmtInVariousFormats construct()    {        return new ITSGetFileFromDocMgmtInVariousFormats();    }}
 
  • Verified answer
    Martin Dráb Profile Picture
    231,837 Most Valuable Professional on at
    Convert PDF file attachment to Base64 string using X++
    Consider replacing your code with ERDocuRef_Extension::getFileContentAsBase64String(_docuRef).
    If you don't want to take a dependency on Electronic Reporting, look into getFileContentAsBase64String() and use the same approach to obtain a stream. Then use ToArray() to get a byte array from the stream and System.Convert::ToBase64String() to convert the array to a Base64 string.

    Update: My reply disappeared after sending and before I typed it again, Rhushikesh found a solution.
  • Verified answer
    Rhushikesh R Profile Picture
    752 on at
    Convert PDF file attachment to Base64 string using X++
    This is sorted. Below code works fine for me.

    Thank you!
     
    DocuRef docuRef;
    
    select docuRef
                where docuRef.RecId == 68719599267;
                
    BitMap fileContents =  DocumentManagement::getAttachmentAsContainer(docuRef);
    str fileBase64Str = con2base64str(fileContents);
    
    info (strFmt('base string: %1', fileBase64Str));
     
  • Martin Dráb Profile Picture
    231,837 Most Valuable Professional on at
    Convert PDF file attachment to Base64 string using X++
    First of all, let me re-post your code in a readable way (unfortunately this site has a bug that breaks formatting in the question, but it works in replies) and simplify it a bit:
    internal final class ITSGetAttachedFileRunnabl
    {
        public static void main(Args _args)
        {
            DocuRef docuRef = DocuRef::findRecId(68719599267);
           
            ITSGetFileFromDocMgmtInVariousFormats::construct().readFromDocuRefAttachments(docuRef);
        }
    }
     
    using Microsoft.Dynamics.ApplicationPlatform.Services.Instrumentation;
    using Microsoft.DynamicsOnline.Infrastructure.Components.SharedServiceUnitStorage;
    using Microsoft.Dynamics.AX.Framework.FileManagement;
    using Microsoft.WindowsAzure.Storage;
    using Microsoft.WindowsAzure.Storage.Blob;
    
    internal final class ITSGetFileFromDocMgmtInVariousFormats
    {
        str docfiletype;
        Microsoft.Dynamics.AX.Framework.FileManagement.IDocumentStorageProvider storageProvider;
        
        public void readFromDocuRefAttachments(DocuRef _docuRef)
        {
            Blobdata blobContainer;
             
            if (_docuRef.isValueAttached())
            {
                var docuValueloc = _docuRef.docuValue();
                str downloadUrl = docuValueloc.Path;
                if (!downloadUrl || docuValueloc.Type == DocuValueType::Others)
                {
                    str accessToken = DocumentManagement::createAccessToken(_docuRef);
                    downloadUrl = Microsoft.Dynamics.AX.Framework.FileManagement.URLBuilderUtilities::GetDownloadUrl(docuValueloc.FileId, accessToken);
                }
                
                storageProvider = Docu::GetStorageProvider(_docuRef.docuType(), false);
                var docContents = storageProvider.GetFile(docuValueloc.createLocation());
                AsciiStreamIo file = AsciiStreamIo::constructForRead(docContents.Content);
                // download file on browser
                file.read();
                str displayUrl = DocumentManagement::getAttachmentPublicUrl(_docuref);
                
                Browser br = new Browser();
                br.navigate(displayUrl);
                
                // To byte - working
                System.IO.StreamReader streamReader = new System.IO.StreamReader(docContents.Content);
                System.Byte[] bytes;
                System.Text.Encoding getUTF8 = System.Text.Encoding::get_UTF8();
    
                bytes = getUTF8.GetBytes(streamReader.ReadToEnd());
    
                // To memorystream
                System.IO.MemoryStream stream = new System.IO.MemoryStream(bytes);
    
                // to binary and blob container
                Binary binaryData = Binary::constructFromMemoryStream(stream);
    
                if (binaryData)
                {
                    blobContainer = binaryData.getContainer();
                }
    
                // to base 64
                str fileBase64Str = con2base64str(blobContainer);
                info (strFmt('base: %1', fileBase64Str));
                
                DocuValue docuValue;
                select firstonly docuValue
                    where docuValue.RecId == _docuRef.ValueRecId;
                info (strFmt('Original filename is %1', docuValue.originalFileName));
            }
        }
        
        public static ITSGetFileFromDocMgmtInVariousFormats construct()
        {
            return new ITSGetFileFromDocMgmtInVariousFormats();
        }
    }
     

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Daivat Vartak – Community Spotlight

We are honored to recognize Daivat Vartak as our March 2025 Community…

Announcing Our 2025 Season 1 Super Users!

A new season of Super Users has arrived, and we are so grateful for the daily…

Kudos to the February Top 10 Community Stars!

Thanks for all your good work in the Community!

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 293,025 Super User 2025 Season 1

#2
Martin Dráb Profile Picture

Martin Dráb 231,837 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,156 Moderator

Leaderboard

Product updates

Dynamics 365 release plans