We have a client currently on NAV2013 R2 who is expressing interest in upgrading to NAV2018. However, they have various legacy customizations that i'm concerned may not be possible with the new NAV 2018 "AL 2.0" extensions development model.
If I understand correctly, the "dotnet" datatype was removed for AL (this is mentioned in Microsoft's AL github issue tracker page and any references to the dotnet datatype is completely absent in the NAV2018 developer documentation). This presents a challenge because we utilize this datatype for various things Dynamics NAV is not capable of, including but not limited to:
Regular Expressions
e.g. validating email addresses, URLs, etc. via System.Text.RegularExpressions. We've found NAV's built-in email address validation inadequate and consequently had to roll our own email address validation via regex matching.
HTML string formatting
We use System.Web.HttpUtility.HtmlEncode to properly encode HTML strings for SMTP HTML emails sent from NAV. What's the workaround? roll our own HtmlEncode function in a codeunit?
Folder I/O
Although NAV can create and read files via FILE/INSTREAM/OUTSTREAM, there are no built-in functions for creating and deleting folders
The "FILE" virtual table's "Name" field (which is the full path to a directory or file) has an 80 character limit, requiring us to utilize System.IO.Directorory to get around this limitation (file and directory paths in the current session's %TEMP% directory on the service tier server can be quite long)
Launching a client or server process (used for tasks like PDF merging & watermarking, image conversion, etc)
The SHELL function is no longer available in 3-tier NAV, requiring us to utilize dotnet classes in the System.Diagnostics namespace to launch a process
Consuming 3rd party SOAP calls from AL
Using the NAV2019 HttpClient and XmlDocument data types to call a third party SOAP service are inadequate replacements and will incur quite a bit of added development overhead
Calling client-side dotnet datatypes from the Windows RTC
I just don't see how this is possible anymore with AL if the dotnet type is unavailable for AL
Question -
How are the above sample use cases to be achieved via NAV2018 AL development? We are aware that the "automation" (COM) datatype is still available, but even that has its limitations (cannot be run form the NAV Server for instance). Do we need to leverage HttpClient/XmlDocument/JsonObject to do all the above (except folder I/O at least)?
*This post is locked for comments
Thanks Stefano on the GitHub link - will do!
Sure, here is the official place where you can submit requests on AL and Extensions features:
The team is listening...
Thanks Stefano - unrelated question. Can you offer any advice on how I can follow these developments more closely with Microsoft, and possibly, where to post my feedback on suggestions for future NAV releases?
I currently work for a Microsoft Partner in Canada. Although I've been working on and off in NAV for several years (I'm primarily a .NET and node.js developer where I work), it wasn't until this past year however that my responsibilities have almost entirely shifted to NAV (go figure, just when this transition to extensions is gaining momentum).
They're working on that... things could change in a near future, at least for OnPremise.
Stefano,
Very helpful feedback thank you - that's what I feared. If I have a client who relies on a lot of legacy data file integration, it's looks like extensions is a non-starter (unless the client is willing to eat the cost on a complete re-write on how they consume and export data in and out of NAV - none of their file-based integration customizations will work in AL 2.0) - that's going to be a hard sell.
To further your point, on-premise filesystem access will only work if customizations are done the old C/AL way (which I keep on reading should be avoided if possible in favor of AL 2.0 and VS Code). If a client wishes to go with extensions, an on-premise NAV using extensions will be just as neutered as NAV on the cloud.
I think it was very short-sighted of Microsoft to flat-out deny 100% file system access and shut out all the helpful functions otherwise found in codeunit 419. What would have been a better solution is for NAV to whitelist certain directories that are safely sandboxed between tenants. Even better, offer another means to securely mount remote directories in NAV e.g. SFTP.
Disappointing.
Thanks Audrey - that's what I figured (i.e. use HttpClient to to call an on-prem or azure REST endpoint and use the back end language of your choice e.g. node.js, .NET MVC, Web API, etc) - I was curious to hear what the community to say on the matter, this confirms my suspicions.
You're right, personally I had a big internal discussion on these topics with the product team in the last year. Unfortunately AT THE MOMENT file system management is admitted only for On-Premise, if you work with AL and Extensions 2.0 you can't use these primitives.
I think that things could change but actually this is the situation. Azure Functions could be a solution for certain situations but not for all...
You can move part of your dotnet functionality to Azure function and call it from NAV:
I found some more interesting utility functions in codeunit 10 "Type Helper" to facilitate tasks like HTML and URL encoding, as well as regex string validation. All the relevant functions in this codeunit have FunctionVisibility=External which according to my research, means those functions can be called from an extension.
There doesn't appear to be any adequate codeunit utility function for base64 encoding/decoding (which is otherwise really easy to do with .NET). So base64 encoding binary data from an extension is a problem.
Getting back to folder I/O functions in codeunit 419, some functions are available from extensions...MOST are not (as demonstrated by each function's internal/external FunctionVisibility flag).
[External]
PROCEDURE ClientDirectoryExists@42(DirectoryPath@1001 : Text) : Boolean;
[Internal]
PROCEDURE CreateClientDirectory@49(DirectoryPath@1000 : Text);
[Internal]
PROCEDURE UploadClientDirectorySilent@57(DirectoryPath@1000 : Text;FileExtensionFilter@1002 : Text;IncludeSubDirectories@1003 : Boolean) ServerDirectoryPath : Text;
[Internal]
PROCEDURE ServerDirectoryExists@48(DirectoryPath@1000 : Text) : Boolean;
[Internal]
PROCEDURE ServerCreateDirectory@47(DirectoryPath@1000 : Text);
[Internal]
PROCEDURE ServerCreateTempSubDirectory@59() DirectoryPath : Text;
[Internal]
PROCEDURE ServerRemoveDirectory@55(DirectoryPath@1000 : Text;Recursive@1001 : Boolean);
[Internal]
PROCEDURE GetServerDirectoryFilesList@64(VAR NameValueBuffer@1000 : Record 823;DirectoryPath@1001 : Text);
Some comments to Microsoft on this. I understand the need to decorate these functions with FunctionVisibility = Internal (I totally understand that a multi-tenant environment in NAV TENERIFE needs to be sandboxed and folder I/O like this should be strictly off-limits), but this really limits what extensions can do with regards to certain file operations that may be necessary (think legacy file integrations where the ERP may need to create folders on the fly to move files around. These [Internal] flags makes it impossible for an extension to do these things.
Secondly, where is the logic in making functions like GetServerDirectoryFilesList internal (apart from sandboxing NAV365 from revealing files it shouldn't)? The virtual file table is not a reasonable substitute with its ~80 char path limitation.
Also, where the value in making temp folder operations such as CreateClientDirectory an internal function? Where is the danger in an add-in doing this?
Is it reasonable to conclude that if a NAV client needs to integrate NAV via enumerating/importing/exporting files, that AL extensions should be avoided?
Most of my questions still apply, however with regards to Folder I/O, it looks like codeunit 419 "File Management" handles various folder I/O (both client and server), negating the need for any use of the dotnet System.IO namespace, nor are the directory path lengths limited (C419 doesn't use the File virtual table)
Client directories:
ClientDirectoryExists
CreateClientDirectory
DeleteClientDirectory
Server directory functions:
ServerDirectoryExists
ServerCreateDirectory
ServerCreateTempSubDirectory
ServerRemoveDirectory
GetServerDirectoryFilesList
Would be very interested what the community suggests for the other use cases I identified where the dotnet datatype is used, since those appear to still be gaps.
Stay up to date on forum activity by subscribing. You can also customize your in-app and email Notification settings across all subscriptions.
André Arnaud de Cal... 291,228 Super User 2024 Season 2
Martin Dráb 230,056 Most Valuable Professional
nmaenpaa 101,156