Generate Symbols in a Modern Development environment with Microsoft Dynamics NAV 2018

Original URL…

With the general availability of Microsoft Dynamics NAV 2018 in the first week of December 2017, the new and Modern development environment experience becomes more and more used by developers; side by side with the C/SIDE development environment.

Working with a standard CRONUS database is pretty easy, while every developer would like to give it a spin with their own customized database. In this scenario, it is paramount to have the appropriate symbols generated in order to be successfully pulled out by AL Extension command in Visual Studio Code and develop a custom extension against a proper customized source database.

Installing CSIDE Development Environment side by side with Modern Development Environment is duly described in the docs, as well as how to generate / re-generate symbols. For more information, see

Here are a few tips that can be helpful when generating symbols.


Generating AL Objects from JSON

Original URL…

As interacting with WebServices, especially JSON/REST based WebServices, becomes more and more important, it was very good to see that the new NAV dev environment made it quite easy to do exactly that a couple of releases ago. After reading AJ Kauffmann’s excellent blog post on that topic, I had the idea to auto-generate that code based on a JSON file, so that you no longer need to write a single line of code to get a working base structure. With release 2.3.0 of my VS Code extension this is now possible!

Configuring Visual Studio Code to Use Modern Development Environment with Dynamics NAV 2018

Original URL…

After installing Dynamics NAV 2018, I want to configure Visual Studio Code with Dynamics NAV to use new Development tool.

Before we start lets verify few things and update accordingly.


You can download VS Code from here:-Click to download Visual Studio Code

Install and Launch the Visual Studio Code.

Now Click View -> Extensions.


Click on … to open the extension menu.

Click on Install from VSIX


You can find VSIX file on the installation medium path:

“ModernDev\program files\Microsoft Dynamics NAV\110\Modern Development Environment”

or in the

“C:\Program Files (x86)\Microsoft Dynamics NAV\110\Modern Development Environment”


This will install AL Language Version 0.12.15355


Once the Extension installation is complete, follow below steps

Press Alt+A, Alt+L to trigger the Go! Command


Enter Project Name and Press Enter


Choose “Your own server”

Once you select the “Your own server” you will see a code like below in the “launch.json” file.


Update the information to look similar to below:-


I have updated my ServerInstance as DynamicsNAV110 (you check your instance name if changed while installing server)

I have updated my Authentication as Windows (I am using Windows authentication update what yours use accordingly)

I have added Port as 8049 (please check and use accordingly you are using the port, if using default 7049 then this step not required)

Now save your File. And Press <CTRL + F5>.


Enter your Credentials.

The server url and the web client url are assumed to be the same. That is not the case. The two settings we talked about above, the server url and the developer port number, are the only settings you need in the launch.json.

When VS Code publishes the extension to the NAV server, the NAV server returns the web client url as a response. This url is then opened in the browser. No setting needed in the launch.json at all.

The NAV server reads that setting from the Web Client Base Url server setting.



Your Extension is published, you can verify as below:


Now you are good to go with developing your Extensions using New Modern Development Tool using AL.

AL Extensions: Importing and Exporting Media Sets

Original URL…

One of the things that has changed when you are building V2 extensions for a cloud environment is that you cannot access most functions that work with physical files.

This presents a bit of a challenge when it comes to working with the media and media set field types, as the typical approach is to have an import and export function so that a user can get pictures in and out of the field.

An example of this is the Customer Picture fact box that’s on the Customer Card:


As you can see, the import and export functions in C/Side leverage the FileManagement codeunit in order to transfer the picture image to and from a physical picture file. These functions are now blocked.

So…..we have got to take another approach. Enter streams.

Using the in and out stream types we can recreate the import and export functions without using any of the file based functions.

An import function would look like the following. In this example, the Picture field is defined as a Media Set field.

local procedure ImportPicture();
   PicInStream: InStream;
   FromFileName: Text;
   OverrideImageQst: Label 'The existing picture will be replaced. Do you want to continue?', Locked = false, MaxLength = 250;
   if Picture.Count > 0 then
      if not Confirm(OverrideImageQst) then

   if UploadIntoStream('Import', '', 'All Files (*.*)|*.*', FromFileName, PicInStream) then begin
      Picture.ImportStream(PicInStream, FromFileName);

The UploadIntoStream function will prompt the user to choose a local picture file, and from there we upload that into an instream. At no point do we ever put the physical file on the server. Also note that the above example will always override any existing picture. You do not have to do this as media sets allow for multiple pictures. I’m just recreating the original example taken from the Customer Picture page.

For the export we have to write a bit more code. When using a Media Set field, we do not have access to any system function that allows us to export to a stream. To deal with this all we need to do is loop through the media set and get each of the corresponding media records. Once we have that then we can export each of those to a stream.

That would look like this:

local procedure ExportPicture();
   PicInStream: InStream;
   Index: Integer;
   TenantMedia: Record "Tenant Media";
   FileName: Text;
   if Picture.Count = 0 then

   for Index := 1 to Picture.Count do begin
      if TenantMedia.Get(Picture.Item(Index)) then begin
         if TenantMedia.Content.HasValue then begin
            FileName := TableCaption + '_Image' + format(Index) + GetTenantMediaFileExtension(TenantMedia);
            DownloadFromStream(PicInstream, '', '', '', FileName);

We use the DownloadFromStream function to prompt the user to save each of the pictures in the media set. As in our first example, there are no physical files ever created on the server, so we’re cloud friendly!

You may notice that I use the function GetTenantMediaFileExtension in the export example to populate the extension of the picture file. Since the user can upload a variety of picture file types, we need to make sure we create the file using the correct format.

The function to do this is quite simple, however there is no current function in the product to handle it, so you’ll have to build this yourself for now. Hopefully in the near future this function will be added by Microsoft.

local procedure GetTenantMediaFileExtension(var TenantMedia: Record "Tenant Media"): Text;
   case TenantMedia."Mime Type" of
      'image/jpeg' : exit('.jpg');
      'image/png' : exit('.png');
      'image/bmp' : exit('.bmp');
      'image/gif' : exit('.gif');
      'image/tiff' : exit('.tiff');
      'image/wmf' : exit('.wmf');

NAV Development Preview – December Update

Original URL…

Welcome to our update for the Developer Preview; the December update. As usual, we’ve fixed a lot of issues reported by you, for more information view the list of fixed issues, In addition to that we’re announcing the following changes as you can see listed below. To jump directly to an updated image go to the Azure Gallery sign up at

The AL Formatter

The AL Language Visual Studio Code extension now offers the option of automatically formatting your source code. The auto-formatter can be invoked to format an entire AL document or a pre-selected range.

  • In an existing project, open the document that you want to format, right-click inside the document, and then choose Format Document.
  • To format a range, open the document that you want to modify, select the specific range to format, right-click it, and then choose Format Selection.

Earlier blog posts:

NAV Development Tools Preview – November Update

NAV Development Tools Preview – October Update

NAV Development Tools Preview – September Update

NAV Development Tools Preview – August Update

NAV Development Tools Preview – July Update

NAV Development Tools Preview – June Update

NAV Development Tools Preview – April Update

NAV Development Tools Preview – March Update

NAV Development Tools Preview – February Update

NAV Development Tools Preview – January Update

Announcing the Preview of Modern Development Tools for Dynamics NAV

Things that made me say “Wow!” about Microsoft Dynamics NAV 2018

Original URL…

After a fair wait (considering we were accustomed to a release every year), and after several rumors about its publication or delay, the new release of Microsoft Dynamics NAV, NAV 2018, includes some interesting features.

My reaction after a first look: Wow!

Although I had seen the Community Technology Preview (CTP) versions of the product, the Release to Manufacturing (RTM) version was a surprise, as it often is. Microsoft (rightly) keeps many details hidden or little documented until the time of release.

The first thing you notice is that now Microsoft, in the product launch documentation (What’s New), always presents the Web Client, while also maintaining the role-tailored client (RTC). As NAV evolves into a cloud-first application, it makes sense now to use only the Web Client or NAV Universal App for mobile devices.  The Web Client has now reached and passed the Windows Client, and most of the features related to user customization work only for the Web Client.

Microsoft has published a full list of new features on PartnerSource, as well as deployment and development documentation. I will review my favorite new features here.

Features for application users

User Personalization & Web Client: It is now possible for users to configure the Web Client individually, treating it like a desktop or interactive whiteboard where they can customize almost everything, including repositioning the Freeze Pane, moving and hiding page parts, repositioning or hiding Cues and Cue Groups, and using ListParts on Role Centers. It’s an awesome look!

PPreview reports on the Web client: Another very helpful feature which enables you to print preview without saving files.

Great Excel integration, with preconfigured Excel reports. The Business Manager and Accounting Role Center has a new option in the ribbon for Excel Reports. Users may select from a dropdown menu of preconfigured reports (see graphic) that is ready to print from Excel. Among those reports are such broadly useful ones as Balance Sheet, Cash Flow Statement and Trial Balance.

Another nice feature is User Tasks, with which you can create tasks to remind you of work to be done, or to assign tasks to yourself or other users (a feature like the CRM Assign function or Service Task). I had submitted this request to MS Connect long ago – nice to see it!

Manage Flows Integration: Embedded Microsoft Flow. Now it is possible to use Microsoft Flow for sales document approval requests.

The Image Analyzer extension uses powerful image analytics provided by the Computer Vision API for Microsoft Cognitive Services to detect attributes in the images. Some examples of its utility are in recognizing a person’s gender or age or identifying items by attributes like type and color.

Features for technical/developer users

There are now two development environments in the installation:

  • the old development environment based on C/SIDE & C/AL
  • the new Modern Development Environment, based on Vs Code+ AL, usable for both NAV 2018 and Tenerife. (See graphic.)

You make your selection in the “Customize the Installation” window during setup (see graphic).

I detail the differences between the two environments in this entry on my Roberto Stefanetti NAV Blog.

Extensions Target Level: Extensions 2.0 publishable/installable: In Extensions 2.0 exists a concept of “levels of extensions,” used to determine the different classifications and capabilities of an extension package. In order the levels progress as follows: Personalization, Extension, Solution, Internal.

In VSCode development, you specify this in the app.json file using the “target” property. This restricts what is allowable within the Extension. On the server side, you have the ability to set the level of 2.0 extensions that you want to allow to be publishable/installable. This enables admins with control over which kinds of Extension they want to have on their systems.

Default & Service Language: NAV Server instance configuration includes two new settings for controlling the Dynamics NAV client language, being:

  • Default Language, which specifies which of the installed Dynamics NAV languages on the server instance will be the default language in the clients
  • Supported Languages, which specifies which of the installed Dynamics NAV languages on the server instance will be available for use in the clients

Change Server Setting Without Restart – Finally! A great feature, as some come configuration changes to the Dynamics NAV Server can be done without a server restart.

Obsolete State for Tables, Fields, and Kays: Table object, fields, and keys include the ObsoleteState and ObsoleteReason properties, used to communicate to developers when a table or key is or will become obsolete.

PowerShell cmdlets: Many new PowerShell cmdlets are now available, both for administering, extensions, development, and deployment. Microsoft provides more detail in this documentation.

Universal App & Windows 10 Continuum: The NAV Universal App for mobile devices is today available on more devices, and a new and interesting feature is Continuum. This technology is a Windows 10 feature that allows you to project your phone to your big screen. You can also interact with keyboard and mouse through Bluetooth, when the connected NAV Universal App is configured to automatically switch to the desktop experience.

ASP.NET Core: The Dynamics NAV web server components now run on ASP.NET Core – cool! ASP.NET Core enables NAV to reach new heights in cloud scalability.

OData V4 Bound Actions: NAV 2018 runs OData web services based on OData V4. OData Relational Query Support provides the ability to include related entities inline within a single OData V4 response. A great feature…all data available in a single call!

Stay tuned for the next wave of updates, and have a nice first experience with NAV 2018!

How to connect Visual Studio Code with NAV 2018

Original URL…

Last couple of days, I got a number of questions from people that all came down to the same issue: how to set the correct settings in the launch.json so Visual Studio Code can connect to NAV 2018. In most cases I saw the same mistake being made. A logical mistake, but also one that leaves you probably wondering why it works that way.

Let’s assume you have enabled the development port in your NAV 2018. Look here to read how that is done.

When you create a new workspace in VS Code with the AL:Go! command, you get by default a launch.json that looks like this:




Basically the only thing you need to change is the servername. In my case that would be navserver. Some people also change the default developer port 7049 to another port number, let’s say 7149. A common mistake is to put that port number into the server url.



Let’s see what happens when we try to download the symbol files.


It uses port number 7049! How is that possible?

The port number in the server url is just ignored. Instead you should specify the port number with a separate setting. If that setting is missing, then the default port number 7049 is used. Let’s specify the port number and see what happens.


Let’s download the symbol files again, and watch the url.


Conclusion: do not specify a port number in the server url. Instead, use the port setting to specify the developer port number.


Another common mistake is that the server url and the web client url are assumed to be the same. That is not the case. The two settings we talked about above, the server url and the developer port number, are the only settings you need in the launch.json.

When VS Code publishes the extension to the NAV server, the NAV server returns the web client url as a response. This url is then opened in the browser. No setting needed in the launch.json at all.

The NAV server reads that setting from the Web Client Base Url server setting.

Let’s prove that with an example. In the next screenshot, I set the key to a different value. Sorry, it’s PowerShell, I only have NAV 2018 installed with docker images. 😉


How to check the output? Well, I can of course show a browser screen with that url, but would that prove my point? So I figured that a Fiddler trace would probably more convincing. Here is the Fiddler trace when VS Code publishes the extensions to the server.


Look at the response, it contains the setting that I did with the PowerShell command.

And here is what happens when the Web Client Base Url is not set:


I hope this demystifies how VS Code and the NAV server work together!

Programming in AL

Original URL…
AL is the programming language that is used for manipulating data (such as retrieving, inserting and modifying records) in a Dynamics 365 for Finance and Operations, Business edition database, and controlling the execution of the various application objects, such as pages, reports, or codeunits.

With AL, you can create business rules to ensure that the data which is stored in the database is meaningful and consistent with the way customers do business. Through AL programming, you can:
•Add new data or transfer data from one table to another, for example, from a journal table to a ledger table.
•Combine data from multiple tables into one report or display it on one form or page.

Where to write AL code

Almost every object in Dynamics 365 for Finance and Operations, Business edition contains triggers where you can add your AL code. Triggers exist for the following objects:
•Table fields
•Data items

You can initiate the execution of your AL code from the following:

•Any object that has an instantiation of the object that contains AL code. An example of an instantiation is a variable declaration.

Note:If the AL code is in a local method, then you cannot run it from another object.

Guidelines for placing AL code

We recommend the following guidelines for AL code:
•In general, put the code in codeunits instead of on the object on which it operates. This promotes a clean design and provides the ability to reuse code. It also helps enforce security. For example, typically users do not have direct access to tables that contain sensitive data, such as the General Ledger Entry table, nor do they have permission to modify objects. If you put the code that operates on the general ledger in a codeunit, give the codeunit access to the table, and give the user permission to execute the codeunit, then you will not compromise the security of the table and the user will be able to access the table.
•If you must put code on an object instead of in a codeunit, then put the code as close as possible to the object on which it operates. For example, put code that modifies records in the triggers of the table fields.

Reusing code

Reusing code makes developing applications both faster and easier. More importantly, if you organize your AL code as suggested, your applications will be less prone to errors. By centralizing the code, you will not unintentionally create inconsistencies by performing the same calculation in many places, for example, in several triggers that have the same table field as their source expression. If you have to change the code, you could either forget about some of these triggers or make a mistake when you modify one of them.
Getting Started with AL…

Steps to set up a sandbox environment and Visual Studio Code

Go through the following steps to set up a sandbox environment. With the preview you get sample code that compiles and runs with just a few commands.+

1) Sign up for a Dynamics 365 for Financials sandbox.
2) Download Visual Studio Code.
3) Download the AL Language extension.
4) Press Alt+A, Alt+L to trigger the Go! command, and then choose Cloud.
5) Enter the credentials you provided for the sign up, and then Download symbols.
6) Press F5 to deploy and run the extension on your online sandbox tenant. +


Use Ctrl+Shift+P to clear the credentials cache if you want to deploy against a different environment.+

You now have a HelloWorld sample that compiles and runs. The JSON files in the project are automatically updated with the settings that allows you to press F5 to build and deploy the solution.+


If symbols are missing, you will be prompted to download them.+

As this feature is still in preview you might run into unrecoverable issues from time to time. In these cases, use Reset Sandbox to reset the sandbox and start from a clean environment.+

Interested in an on-premise version? It’s just as easy. Just sign up by following these steps.+

1) First, you will need an Azure subscription, sign up for a free subscription.
2) Go to the Developer Preview.
3) When you have a virtual machine set up, you will see a welcome text and here you can choose to try out the developer preview following the instructions on the screen. +


Build and get inspired by our sample library on GitHub.+

JSON file settings

There are two JSON files in the project; the app.json file and the launch.json file. The files are automatically generated for your project. For more information, see JSON files.+

The symbol file

The symbol file contains metadata of the application. This is what your extension is being built on, and therefore the symbol file must be present. If it is not present, you will be prompted to download it. For more information about the platform symbol file, see Symbols.+

Installing and publishing an extension

To make your extension available to users, the package must be published to a specific Microsoft Dynamics NAV Server instance. The extension can be installed for one or more tenants. For more information about how to install and publish an extension, see How to: Publish and Install an Extension V2.

AL Development Environment…(Samples) – (GitHub).

How to enable ModernDev on NAV2018

Original URL…

Go into the Dynamics NAV 2018 Administration, select the Development fast tab, check Enable Developer Service Endpoint.

Now port 7049 is open, and you have access to use Visual Studio Code.

You should also specify the target of your extensions:

So far chose internal … more on this later….

To get Visual Studio Code up and running, you need the VS extension; it can be found here in the install image:

\ModernDev\program files\Microsoft Dynamics NAV\110\Modern Development Environment\ALLanguage.vsix

In Visual Studio Code, use Install from VSIX from the extension … menu:

Install it, and you should get this:

Version 0.12.15355 is the version delivered with NAV2018.

I prefer my NAV installation running with NavUserPassword authentication, so I have changed the demo NAV2018 install into that. So the next step is to edit your launch.json file:

In my case, I have copied my self-signed certificate from Personal to Trusted Root to prevent certificate errors in VS Code:


The extension is now installed on my NAV2018