web
You’re offline. This is a read only version of the page.
close
Skip to main content

Announcements

No record found.

News and Announcements icon
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 758
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();    }}
 
I have the same question (0)
  • Martin Dráb Profile Picture
    239,040 Most Valuable Professional on at
    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();
        }
    }
     
  • Verified answer
    Rhushikesh R Profile Picture
    758 on at
    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));
     
  • Verified answer
    Martin Dráb Profile Picture
    239,040 Most Valuable Professional on at
    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.

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

Introducing the 2026 Season 1 community Super Users

Congratulations to our 2026 Super Stars!

Meet the Microsoft Dynamics 365 Contact Center Champions

We are thrilled to have these Champions in our Community!

Congratulations to the March Top 10 Community Leaders

These are the community rock stars!

Leaderboard > Finance | Project Operations, Human Resources, AX, GP, SL

#1
Giorgio Bonacorsi Profile Picture

Giorgio Bonacorsi 658

#2
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 468 Super User 2026 Season 1

#3
Syed Haris Shah Profile Picture

Syed Haris Shah 333 Super User 2026 Season 1

Last 30 days Overall leaderboard

Product updates

Dynamics 365 release plans