Getting Started with the NAV Development Environment
If you are reading this book, you probably know what Microsoft Dynamics NAV is and want to delve deeper into its customization possibilities. This quick start guide will help you understand different aspects of the NAV development environment, customization of application code, the user interface, and data exchange processes, debugging your code, and designing reports.
The examples in this book are based on Dynamics NAV 2018, but the Client/server Application Language (C/AL) syntax remains mostly the same since older versions. Recent NAV releases introduced specific language structures designed for interaction with .NET classes and interfaces, as well as task scheduling and handling new UI elements. But these topics are beyond language fundamentals, and hence are not covered in this quick start guide. Code samples accompanying the book can be compiled and run in any version of NAV starting from 2013.
The opening chapter of the book gives an overview of the setup and configuration process, and leads into the integrated development environment. It will cover the following topics:
- Installing the NAV development environment
- Managing NAV server configuration with the Microsoft Management Console (MMC)
- Managing NAV installation with the NAV Administration Shell
- Introducing the Object Designer
- Exporting and deploying NAV objects
Installing the NAV development environment
Installation of the NAV demo environment is very simple. Running the setup and selecting a predefined configuration is all it takes to install the NAV server with the demonstration database and development tools. On the other hand, experienced users can customize the installation according to their personal needs.
Setup configuration
Installation is started by running setup.exe from the root folder of the NAV DVD. After accepting the license agreement, you will be offered two options: either install the predefined demo configuration (install demo), or choose installation options manually (choose an installation option).
If you prefer to run the default installation, all necessary system components will be installed on the same computer. This option will set up NAV Server, NAV Client, the development environment, and a demonstration database with a demo license. This setup will create a new named SQL Server instance, NAVDEMO, and restore a database, Demo Database NAV (11-0), on this server instance.
If you select the second option while choosing an installation option, a list of configurations will be suggested. Each of these configurations can be further customized, or installed with the predefined set of components.
Developer configuration is a recommended setup step. Besides the components listed previously, it will also install web server components to provide web access to the NAV server. But you should note that this option requires Internet Information Services (IIS) running in Windows authentication mode, which is not supported in basic Windows editions. If you are installing NAV on a computer running under Windows 10 Home or Windows 8 Home editions, this option cannot be installed. In this case, disable the Web Server Components option manually or choose the Install Demo option.
The following screenshot shows the list of components that should be installed. If you choose to disable the optional Web Server Components, select the Not Available option in the installation menu:

Accept all components suggested in this configuration and move to the next step, where you can set up the installation location and other parameters for NAV Server and SQL Server.
Now, if you accept all the default options without changes, the demo database will be created on the default instance of SQL Server (MS SQL Server), if there is one on the computer where the installation is run. If no default instance is found, a new one will be created.
Now you can hit Apply and wait until the installation completes.
License information
A demonstration license uploaded with the demo installation supports limited functionality, and most of the examples in this book will not work under the limited demo license. A development license is required to import and run the sample code files, as well as develop your own objects.
To review the license currently uploaded to the server, choose the menu option Tools | License information. The following line in the license description will tell you that the uploaded license file is intended for demonstration only:
Configuration: NAV 2018 Product Demo
To upload the developer's license, click Upload in the same window and choose the appropriate license file.
Managing NAV server configuration with Microsoft Management Console (MMC)
In the following hands-on example, we will create a copy of the demo database and deploy a new instance of the NAV server connected to the new database. This instance is going to be used as a test server for quality assurance, while the original setup will serve as the development environment. Later in the current chapter, we will see how to move new and modified application objects between databases and servers to make QA (Quality Assurance, or test) and production deployments.
Creating a NAV server instance with MMC
For simplicity, we will run both NAV instances on the same database server. First of all, to prepare another server instance, you need a copy of the demo database. The easiest way to do this is to restore the database from a backup file shipped with the NAV installation DVD. The backup file Demo Database NAV (11-0).bak is located under the SQLDemoDatabase folder on the DVD. When restoring the database, name it NAV 110 Test Database; this name will be used in this chapter.
When the database is restored, we can run MMC and create the service:
- To start the console, press Windows key + R to open the Run dialog.
- In the dialog window, type mmc and press OK.
- Select the Add or Remove Snap-ins command from the File menu or press Ctrl + M.
- Select Microsoft Dynamics NAV from the list of available snap-ins and click Add:

You will be prompted to enter the name of the NAV server you want to connect to. The default value is Local. Leave it unchanged if you are running MMC on the same computer where your NAV Server instance is installed. Otherwise, enter the network name of the server.
The new snap-in will list all instances of the NAV server running on the selected computer. For the brand new demo setup, it shows a single installed server, DynamicsNAV110. Now we want to create another one. Right-click on the snap-in named Microsoft Dynamics NAV (Local) in the left pane, under the console root. In the drop-down menu, select the Add Instance action. To set up a server instance, you need to specify its name and five numbers for TCP ports used by the service. The default values for ports are 7045 through 7048. These ports are already occupied by the demo server installation, so you have to choose some other numbers. For example, these can be ports 7055 through 7059.
These are the NAV Server TCP ports:
Service | Default port number | Port number for the new server instance |
Management services port | 7045 | 7055 |
Client services port | 7046 | 7056 |
SOAP services port | 7047 | 7057 |
Odata services port | 7048 | 7058 |
Development services port | 7049 | 7059 |
Enter NavTestServer in the Server Instance field and confirm instance creation.
All other server configuration options will receive default values. A new server instance will connect to the SQL Server instance NAVDEMO, and open the demo database Demo Database NAV (11-0).
Modifying server settings with MMC
When a new server instance is created, it connects to the default demonstration database, and the database name is what we want to change. To modify the server settings, select the server named NavTestServer in the left pane of the management console and click the Edit button. Database-related settings are grouped under the Database tab. Unfold it and change the value of the Database Name field from the default Demo Database NAV (11-0) to NAV 110 Test Database, then click Save to confirm the changes:

When the setup changes are saved, the server must be restarted for the modification to take effect. In order to do so, select the snap-in named Microsoft Dynamics NAV (Local) under the console root. The management console will display the list of NAV server instances. Select the NavTestServer instance and click Restart in the right pane.
Connecting to the new server instance
To connect the Role Tailored Client to the test server instantiated in the previous section, start the client and choose the Select Server command from the main application menu:

In the ServerAddress field, type localhost:7056/NavTestServer and press Tab. Companies that exist in the database will be shown in the Available Companies window. The actual list of companies depends on the application version you are using. Local database versions for different countries have different demo companies. Select the company you want to open in the client and confirm the selection.
Managing NAV installation with NAV the Administration Shell
The Dynamics NAV Administration Shell is an alternative to MMC. This is a command-line interface that will be familiar to system administrators. Although the graphical interface is easier and more intuitive, the undoubted benefit of the command-line shell is its ability to combine separate commands into complex batch scripts to automate daily administrative tasks.
Creating a NAV Server instance with Administration Shell
To be able to manage NAV server instances, the Administration Shell must be executed with local administrator credentials. In order to do this, select Dynamics NAV Administration Shell in the Windows Start menu, right-click on the application icon, and choose Run as administrator. The Administration Shell will list available commands on startup. NAV Administration Shell is actually a PowerShell command window, and each NAV administration command is a PowerShell cmdlet. With PowerShell functionality, you can get the same list of commands with the Get-Command cmdlet:
Get-Command -Module Microsoft.Dynamics.Nav.Management, Microsoft.Dynamics.Nav.Apps.Management
In the previous section of this chapter, we created a server instance through an MMC snap-in. The same can be done with the New-NavServerInstance cmdlet in the NAV Administration Shell:
New-NAVServerInstance
-ManagementServicesPort 7055
-ClientServicesPort 7056
-SOAPServicesPort 7057
-ODataServicesPort 7058
-DeveloperServicesPort 7059
-DatabaseServer localhost
-DatabaseInstance NAVDEMO
-DatabaseName "NAV 110 Test Database"
-ServerInstance NavTestServer
-ClientServicesCredentialType Windows
Note that we provide all parameters, including TCP ports and the database name. Unlike the GUI approach, there is no need to modify server settings after creating an instance.
Managing the NAV server with the Administration Shell
Now the brand new service must be started. To start it, run the following command in the Administration Shell:
Start-NAVServerInstance -ServerInstance NavTestServer
The same can be done with a Windows system cmdlet, Start-Service:
Start-Service -Name 'MicrosoftDynamicsNavServer$NavTestServer'
Note that, in this case, we must provide the full-service name, which includes a prefix, MicrosoftDynamicsNavServer$. When we operate with cmdlets developed specifically for NAV Administration Shell, we only provide the NAV server instance name to the command. The actual server name always begins with the same string, which is implicitly added to the parameter by NAV cmdlets. Keep this in mind when you develop your own Powershell code and pass service names between NAV and system cmdlets.
When you no longer need the additional server instance, delete it with the Remove-NAVServerInstance cmdlet:
Remove-NAVServerInstance -ServerInstance NavTestServer
There are some other cmdlets available in the NAV Administration Shell that can simplify your daily administration activities.
If you are already familiar with Windows Powershell, you probably know about a very powerful cmdlet, Get-WmiObject, that can retrieve information about available Windows Management Instrumentation (WMI) classes. For example, with Get-WmiObject, you can list all installed NAV services:
Get-WmiObject -Class Win32_Service | Where-Object {$_.Name -imatch "DynamicsNAV"}
Services will be listed, along with their state and some other properties.
The NAV Administration Shell provides a shortcut for this command. Get-NAVServerInstance will yield the same result, displaying a list of available NAV services.
With the PowerShell pipeline, the resulting list can be filtered. For example, here is the command to select only running services:
Get-WmiObject -Class Win32_Service | Where-Object {$_.Name -imatch "DynamicsNAV" -and $_.State -eq "Running"}
Or this is the same without the explicit call to Get-WmiObject:
Get-NAVServerInstance | Where-Object {$_.State -eq "Running"}
Now the result set returned by the previous cmdlet can be sent to the pipeline to stop all running services:
Get-WmiObject -Class Win32_Service |
Where-Object {$_.Name -imatch "DynamicsNAV" -and $_.State -eq "Running"} | Stop-Service
Now start all stopped services:
Get-WmiObject -Class Win32_Service |
Where-Object {$_.Name -imatch "DynamicsNAV" -and $_.State -eq "Running"} | Start-Service
Then restart all running NAV services:
Get-WmiObject -Class Win32_Service |
Where-Object {$_.Name -imatch "DynamicsNAV" -and $_.State -eq "Running"} | Restart-Service
Introducing the Object Designer
NAV presents its development capabilities through its own integrated development environment: Client/Server Integrated Development Environment (C/SIDE).
C/SIDE and application objects
The Dynamics NAV Development Environment is accessed from the Windows Start menu. If you just installed Microsoft Dynamics NAV, the development environment will open the database that was specified during installation. If for some reason the database does not open automatically, choose the Database | Open option from the File menu. This will invoke the open Database dialog, where you can specify the name of your development server and the database.
The first thing you see after starting the development environment is the Object Designer. On first start, the development environment connects to the database specified during the installation. If this does not happen, and all you see is a blank window, choose File | Database | Open from the main menu and select the SQL Server and the database name where the development database was created:

Although these application elements are called objects, they should not be confused with objects in object-oriented programming. C/SIDE does not actually support OOP. Developers can create new objects of existing types, but cannot create new object types or classes.
The following table gives an overview of NAV object types and their functions:
Object |
Description |
Table |
NAV table objects are mapped to SQL Server tables and used to access database data. Tables provide interfaces to read and manipulate data. Table objects are covered in detail in Chapter 3, Tables - Creating Data Structure. |
Page |
The primary method of presenting data to the user is to show it on a page. Nearly everything you see in the client interface is a page. Chapter 4, Designing User Interface, covers the development of the user interface, and pages in particular. |
Report |
Use reports to add reporting capabilities to your application and present user data in a structured way. Read more about reports in Chapter 7, Presenting Data in Reports. |
Codeunit |
A codeunit can be considered as a collection of functions of code that can be used by other objects. This is the equivalent of a library in many other languages. Almost all C/SIDE objects can contain program code, but codeunits are designed solely for this purpose. codeunits are explained in Chapter 2, Codeunits - Structuring C/AL Code. |
Query |
C/SIDE provides developers with a toolbox for designing database queries without the need to write SQL code. Queries help improve the performance of the application when it comes to joining tables to select related records from different sources. Queries are not covered in this book. |
XMLport |
XMLports provide a simple interface for configuring hierarchical data structures in XML format for data exchange. They supply a quick method of exporting and importing data with the minimum amount of programming. More on XMLports in Chapter 5, Exchanging Data with XML Ports. |
MenuSuite |
Links to application areas, pages, and reports are presented in the user interface in a structured user menu through a set of MenuSuite objects. You will design your own user menu in Chapter 4, Designing User Interface. |
All objects are identified by the object type, ID, and name. A sample object created in the next section demonstrates how to create an application object and assign a name and ID to it.
Hello World example
To demonstrate how to design objects in C/SIDE, we will follow a traditional example and write a simple Hello World application. In Dynamics NAV, this is going to be a line of code in the OnRun trigger of a codeunit. To create a codeunit, switch to the codeunits list in the Object Designer window. Click Alt + C, or choose the codeunit icon in the left pane, to select codeunits. To create a new object, press Ctrl + N (or choose File | New action in the main application menu).
The MESSAGE function is used to display a UI message; we will use it to display the greeting. The OnRun trigger is automatically added to the object by the editor, so the only thing to do now is to write a code line that shows the message:
OnRun()
MESSAGE('Hello World');
Now, save the object (File | Save). The new object does not have a name and ID yet, so the first time it is saved, you will be prompted to name the codeunit. Enter 50500 as the ID and Hello World for the codeunit name.
The object name is a string, up to 30 characters long, that should describe the object's function to the developer. It must be unique for each object type. ID is a positive integer number used internally by the system. A NAV developer license allows you to create objects with IDs ranging from 50000 to 50999, and all objects described in this book will receive IDs starting from 50500:

Apart from two fields identifying the object, the dialog contains a Compiled flag that specifies whether the object should be compiled before saving. An uncompiled object cannot be executed, so leave the flag checked and click OK.
Running objects from the Object Designer
To execute the new codeunit, select it in the Object Designer and click the Run button located under the list of objects. This action will start the role-tailored client and execute the object code displaying the Hello World message box.
This method of executing object code is not intended to be employed by users to perform their daily tasks. Normally, objects are invoked from a user menu (we will learn how to do this in one of the following chapters). But it is very useful for debugging and testing purposes to quickly run an object during development. Any object, except MenuSuites, can be executed this way.
Exporting and deploying NAV objects
To exchange objects between different databases, it is possible to export them in an external file and import it into a new destination. NAV supports two file formats for application objects: .txt and .fob. The former is object source code in plain text format, while .fob is a native NAV format containing compiled code. Since objects in the .fob file are already in the compiled state, they don't have to be recompiled after import in order to be executed. Objects imported from text files must be compiled first; otherwise, they cannot be run.
Another significant difference between the two object formats is the license permission required to work with files. To be able to export and import plain text files, you need a developer's license, which allows you to create and edit specific objects being processed. The .fob file format does not impose such restrictions on the file exchange process. This is the reason why .fob files are typically used to export new or modified objects from a development/test environment and deploy them to a production server. Usually, the production server is run under an end user license without development access to application code, and there is no possibility to import plain text files.
Besides, software developers usually don't want to disclose source code when selling their solutions. The native .fob format hides the application source behind compiled bytecode, which is impossible with .txt files.
In the Object Designer window, select the 50500 codeunit you created earlier and choose the menu option File | Export, then select the file location. In the File Type field, choose *.txt as the file format, and press the Save button. This will create a file containing the source code for the codeunit:
OBJECT Codeunit 50500 Hello World
{
OBJECT-PROPERTIES
{
Date=14.08.18;
Time=16:39:41;
Modified=Yes;
Version List=PACKT QSG;
}
PROPERTIES
{
OnRun=BEGIN
MESSAGE('Hello World');
END;
}
CODE
{
BEGIN
END.
}
}
To import the object into another database, open a copy of the demo database and invoke the File | Import command from the main menu. Select the exported file and click Open.
Managing objects with the Dynamics NAV Development Shell
Similar to the NAV 2018 Administration Shell, the NAV 2018 Development Shell provides access to PowerShell cmdlets for the management of application objects. Development tasks, such as object export, import, and compilation, can be automated with the Development Shell. The same as Administration Shell, NAV Development Shell can be run from the Start menu. On startup, it imports several modules. We will now take a closer look at one of them: Microsoft.Dynamics.Nav.Model.Tools.
To list all cmdlets available in the Microsoft.Dynamics.Nav.Model.Tools module, run this:
Get-Command -Module Microsoft.Dynamics.Nav.Model.Tools
As an alternative to the method described previously, the import/export procedure can be performed in the NAV Development Shell. To do it, run the following commands one by one.
The first cmdlet will export objects defined by the Filter parameter from the specified NAV server to the disk:
Export-NAVApplicationObject -DatabaseName "Demo Database NAV (11-0)"
-DatabaseServer "localhost\NAVDEMO" -Path "C:\NAV Objects\COD50500.txt"
-Filter "Type=Codeunit;ID=50500"
Typically, you apply a Filter based on the object type and name, but other object properties can be used for filtering as well. For example, you may want to export all modified objects:
Export-NAVApplicationObject -DatabaseName "Demo Database NAV (11-0)"
-DatabaseServer "localhost\NAVDEMO"
-Path "C:\NAV Objects\Modified.txt" -Filter "Modified=Yes"
Or export all object labeled with the version PACKT:
Export-NAVApplicationObject -DatabaseName "Demo Database NAV (11-0)"
-DatabaseServer "localhost\NAVDEMO"
-Path "C:\NAV Objects\COD50500.txt" -Filter "Version List=*PACKT*"
To import the objects, run the Import-NAVApplicationObject cmdlet:
Import-NAVApplicationObject -Path "C:\NAV Objects\COD50500.txt"
-DatabaseName "Demo Database NAV (11-0)" -DatabaseServer "localhost\NAVDEMO"
Imported objects must be compiled in the new database:
Compile-NAVApplicationObject -DatabaseName "Demo Database NAV (11-0)"
-DatabaseServer "localhost\NAVDEMO" -NavServerName DynamicsNAV110
-Filter "Type=Codeunit;ID=50500"
You can compile all objects in the database, or use the Filter parameter to select a subset.
Now, let's combine all these code samples into one Powershell function that can export, import, and compile the object with a single command. To do this, we will need the PowerShell IDE, which can be started from the Windows Applications menu. The application name is powershell_ide. Place the following code in the PowerShell editor and run it:
if ([Environment]::Is64BitProcess)
{
$RtcFolder =
'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Microsoft Dynamics NAV\110\RoleTailored Client'
}
else
{
$RtcFolder = 'HKLM:\SOFTWARE\Microsoft\Microsoft Dynamics NAV\110\RoleTailored Client'
}
Test-Path $RtcFolder
$IdeModulePath = (Join-Path (Get-ItemProperty $RtcFolder).Path Microsoft.Dynamics.Nav.Ide.psm1)
Import-Module $IdeModulePath
function Deploy-ObjectsToTestServer
{
Param(
[Parameter(Mandatory = $true)]
[string] $DevelopmentDatabaseName,
[Parameter(Mandatory = $true)]
[string] $TestDatabaseName,
[Parameter(Mandatory = $true)]
[string] $DevelopmentServerName,
[Parameter(Mandatory = $false, ParameterSetName =
"SeparateTestServer")]
[string] $TestServerName,
[Parameter(Mandatory = $false, ParameterSetName =
"SingelServerSetup")]
[switch] $SingleServer = $true,
[Parameter(Mandatory = $true)]
[string] $NavServerInstance,
[Parameter(Mandatory = $true)]
[string] $ObjectFilter
)
if ($SingleServer)
{
$TestServerName = $DevelopmentServerName
}
[string] $tempFileName = [System.IO.Path]::GetTempFileName() +
".txt"
Export-NAVApplicationObject
-DatabaseName $DevelopmentDatabaseName -DatabaseServer
$DevelopmentServerName
-Path $tempFileName -Filter $ObjectFilter
Import-NAVApplicationObject
-Path $tempFileName -DatabaseName $TestDatabaseName -
DatabaseServer $TestServerName
Compile-NAVApplicationObject
-DatabaseName $TestDatabaseName -DatabaseServer $TestServerName
-NavServerName $NavServerInstance -Filter $ObjectFilter
}
Now you can easily prepare your modification for testing with a single command:
Deploy-ObjectsToTestServer -DevelopmentDatabaseName "Demo Database NAV (11-0)" -TestDatabaseName "NAV 110 Test Database" -DevelopmentServerName localhost\NAVDEMO -SingleServer -NavServerInstance "NavTestServer" -ObjectFilter "ID=50500..50599"
This command will export all objects with IDs from 50500 to 50599 from the development database, Demo Database NAV (11-0), into a temporary file, import it into the NAV 110 Test Database, and compile all imported objects.
Summary
The first chapter introduced the development environment and the basic object model of Microsoft Dynamics NAV. We installed and configured development tools and instantiated an additional server instance for testing purposes. We learned to create and configure server instances in different ways: with MMC or NAV Administration Shell.
The chapter also gave an overview of other capabilities of the NAV PowerShell harness. Besides administering server instances, it gives access to development tools to automate development activities, such as exchanging objects between databases and compiling them.
Also, we started writing simple C/AL code—a topic that will continue in the next chapter. We will write more advanced codeunits and get familiar with the structure of a codeunit. The second chapter will demonstrate the capabilities of C/AL for accessing the database and manipulating data.