Binary data in AX2012

For a manipulation with binary data (e.g. binary files including images, serialized objects etc.), AX particularly offers classes BinData, BinaryIo and Binary. While the first two ones are the same in AX2012 as in AX2009, Binary got a few new useful methods:

public static Binary constructFromContainer(container _data)
public static Binary constructFromMemoryStream(CLRObject _memoryStream)
public container getContainer()
public CLRObject getMemoryStream()

Binary therefore can serve as a simple interface between AX (using containers) and data streams in .NET environment. The examples below demonstrate how useful it can be and how easy it is.

The following X++ code reads a content of a file to a variable of FileStream type, pass it to MemoryStream and put it to an X++ container via Binary:

System.IO.FileStream fileStream = System.IO.File::OpenRead(filename);
System.IO.MemoryStream memoryStream = new System.IO.MemoryStream();
int size = fileStream.get_Length();
container con;
 
memoryStream.SetLength(size);
fileStream.Read(memoryStream.GetBuffer(), 0, size); //write to MemoryStream
con = Binary::constructFromMemoryStream(memoryStream).getContainer(); //from MemoryStream to container

The second example is in C# and requires proxies for X++ classes Image and Binary. It loads an image from AX using a resource ID and use it on a WPF button:

//Loads image with transparent background from AX
Image axImage = new Image();
axImage.loadResource(1030); //ID of some image
axImage.saveType(ImageSaveType.PNG);
 
//Creates data stream
Binary binary = Binary.constructFromContainer(axImage.getData());
MemoryStream stream = (MemoryStream)binary.getMemoryStream();
 
//Creates System.Windows.Media.Imaging.BitmapImage
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = memoryStream;
bitmap.EndInit();
 
//Sets image to a button
var wpfImage = new System.Windows.Controls.Image();
wpfImage.Source = bitmap;
button1.Content = wpfImage;

4 Comments

  1. Hi Martin,

    Thanks for this information. I have a query on a similiar item.

    1) I have an excel file with attributes which i have loaded onto the resources. Now the excel file is in resource node and no physical file exists on my drive.

    I want to read the attributes based on the template and fill values at runtime and then store it to a physical file.

    My query is how i would read the attributes?

    I have done the following

    #AOT
    #File
    #define.template(‘ExcelData_xls’)
    SysExcelWorkbook workbook;
    container data;
    BinData resourceBinData;
    resourceNode resourceNode;
    BinaryIo file;
    Binary binary;
    container cyrptoBlob;
    System.IO.MemoryStream memoryStream;
    FileIOPermission permission;

    resourceNode = infolog.findNode(#ResourcesPath).AOTfindChild(#template);
    resourceBinData = resourceNode.AOTGetData();

    binary = Binary::constructFromContainer(resourceBinData.getData());
    memoryStream = binary.getMemoryStream();
    cyrptoBlob = binary2cryptoblob(binary, memoryStream.get_Length());

    The cryptoBlob returns a huge container value. I want to read the excel attributes? How can i achieve it?

  2. Hi Santosh,
    I don’t know any way how to open Excel file directly from a memory stream, but it is quite simply from a file, so I would save the resource to a temporary file first:

    #AOT
    Filename path;
    TreeNode node = TreeNode::findNode(#ResourcesPath + #AOTDelimiter + ‘data_xlsx’);
    SysExcelApplication app;

    path = SysResource::saveToTempFile(node);
    app = SysExcelApplication::construct();
    app.workbooks().open(path);

  3. Hi Martin,

    I have a dll file stored in the AX table as a binary data.

    The binary data has a dll file. this file has a method name abc.

    Please let me know how can i acess this method abc.

    Thanks a lot.. in advance.

    Kind Regards,
    Somanna

    • The first thing is to realize that binary data and executable code are two different things. The other is to know how to invoke the code, which depends on what the DLL file contains.

      If the DLL contains a .NET class library (common case but far from the only), you have to load the assembly to the application domain before using it. See Load() method in System.Reflection.Assembly – it even allows you to load the assembly directly from an array of bytes.

Comments are closed.