web
You’re offline. This is a read only version of the page.
close
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 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
    237,801 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
    237,801 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

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Neeraj Kumar – Community Spotlight

We are honored to recognize Neeraj Kumar as our Community Spotlight honoree for…

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

#1
Martin Dráb Profile Picture

Martin Dráb 660 Most Valuable Professional

#2
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 549 Super User 2025 Season 2

#3
Sohaib Cheema Profile Picture

Sohaib Cheema 307 User Group Leader

Last 30 days Overall leaderboard

Product updates

Dynamics 365 release plans