Using base64 encoding and decoding for file transfer in AX 2012
Base64 BinData
If you want to transfer small file data using AX and do not want to make use of shared folders or file uploading, sending your file directly inside your XML message as base64 encoded string is a good option. Base64 gives you the possibility to encode your binary data as text and transfer it inside text based message types like XML and JSON and decode it back as a file on the receipt.
For big files though, like 10MB and bigger, I recommend using binary file transfer instead of base64.
Ax 2012 has built in support for decoding and encoding base64 data type with some missing things and drawback we will mention in this article. I do recommend using AX standard methods to do it and not .NET equivalents in AX 2012, because I doubt marshalling such huge amount of data between CLR Interop and AX performs good enough.
Encoding base64 from AX data
For decoding from AX table stored, container based data, simply use the following function:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public str base64FromData(container _data) { str base64; Bindata bindata; if (_data!=conNull()) { bindata = new bindata(); bindata.setData(_data); base64 = bindata.base64Encode(); } return base64; } |
You can use the same bindata class to load a file from disk instead of loading a container based binary data from database. Do not forget to add a CLR interop permission for this to avoid the error :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
///..................... path = docuRef.completeFilename(); fileIOPerm = new FileIOPermission(path, 'r' ); permissionSet.add(fileIOPerm); interopPerm = new InteropPermission(InteropKind::ClrInterop); permissionSet.add(interopPerm); CodeAccessPermission::assertMultiple(permissionSet); fileExists = System.IO.File::Exists(path); if (fileExists) { bindata.loadFile(path); base64 = bindata.base64Encode(); } //////////////..................... |
If you want to encode simple text (or memo, string) using base64 and send it as base64, you need to load the string to bindata class using setAsciiData() method. Note that bindata class also has a setText() method, we are NOT using that one, it will encode it wrong if you do so:
1
2
3
|
str Memo = "a string "; bindata.setAsciiData(Memo); |
After your file is decoded you can add it directly as a node value in your XML document.
Decoding base64 file from a document
Here is the tricky part, AX decodes base64 fine but causing some problems on base64 prefixes. It does not recognize them. To be able to decode it, you manually need to remove the headers, like the example below, and decode it :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
public container dataFromBase64(str _base64) { int pos; BinData bindata; str base64, base64ext; container data; base64 = _base64; base64ext = '' ; if (base64!= '' ) { pos = strFind(base64, ';' , 1, 60); if (pos) { base64ext = subStr(base64, 1, pos-1); } pos = strFind(base64, ',' , 1, 60); base64 = strDel(base64, 1, pos); bindata = new bindata(); data = BinData::loadFromBase64(base64); bindata.setData(data); } return data; } |
What are those headers and when they come. Some types of base64 data, for example photos taken from a cellphone camera in base64 encoding or images used in web, has descriptor prefix before the data starts. Such as the data below. You can erase them to be able to encode, or store them in a variable, like the code above to determine the file extension of the data later.
After you decode your data into container, you can load it into bindata class (like example above) and save it as file or another form of data using bindata class.
Here are some more tips for you if you want to decode base64 and store it inside AX:
- Do not store big file data in a container or string memo blob field in an AX table if you plan to use that table in AX user interface, like inside a form. Create a separate table to store the data and reference other tables to that one if they want to use the file data. It gives all sorts of problems if you store your data in a table used in a form or other UI object, for example if you want to delete the data from the form, it crashes the client (whereas deleting from the code works fine from the same table).
- If you like to store the XML message you have received with file data, for logging or archive purposes, first strip all the file data out of it and do not store the XML text including base64 data inside. You will again have similar problems like above and if you use AIF XML viewer, it will take ages to load that XML into the viewer. You can replace base64 text with the recid of the data you have stored in your data storage table.
posted on 2023-04-27 09:11 lingdanglfw 阅读(81) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?