What’s new in Business Central 2023 Wave 2 Development, The Hacker Edition!

As has become a tradition, a new release of Business Central also means new features in AL. As usual, I go through the list and then behind the curtain to see what’s new in AL. Check it out:

https://youtu.be/nxF5koGs6bA

In this video, Erik takes us through the complete list of what’s new in Business Central 2023 Wave 2 (BC23) for AL development — and then does what he does best: fires up the .NET decompiler to dig into the compiler DLLs and find features that aren’t on the official list. This is the “Hacker Edition” tradition, and as always, there are hidden gems lurking inside the belly of the beast.

The Official What’s New List

The official development section for BC23 (AL version 12, Business Central 2023 Wave 2) is long this time around. Erik runs through each item with commentary:

Easy Management of System Application Permissions

System objects can now be assigned to permission sets using logical groupings rather than one-by-one. Erik notes this feels more like an administration feature than a development one, and considers it somewhat miscategorized.

AL Language Extension Versions on VS Code Marketplace

You can now get previous versions of the AL Language extension directly from the Visual Studio Code Marketplace. Erik demonstrates that he’s already on version 13 (pre-release) and can easily switch between release and preview versions. This capability has actually been available since earlier in the year.

Find All References for Triggers, System Methods, and Trigger Events

This is a significant improvement. Previously, finding where records were inserted into a certain table across a large customization was extremely difficult in AL — it was one of the few reasons Erik still occasionally opened a C/SIDE-era tool. Now, Find All References works on system functions like Insert, Modify, and trigger events.

Inlay Hints for Parameters and Return Types

The editor now shows inlay hints — those subtle gray annotations that display parameter names and return types inline. Erik is on the fence about whether he likes this feature, noting that some hints look a bit odd, especially with AL’s unique syntax patterns like SetContext. The good news is it’s configurable — you can turn it off in VS Code settings under Extensions → AL Language → Inlay Parameter Names.

Hover Over Label Variables to See String Values

A small but handy improvement: hovering over a label variable in the editor now shows you the actual text content of the label in a tooltip.

New Output Folder Setting for App Files

Previously, the compiled .app file always landed in the root folder of your extension project. Now you can specify a custom output folder. This is especially useful when your source code lives in a read-only checked-out area and you need to output the compiled app elsewhere.

More Sampling Intervals for Snapshot and Inline Profiler

This feature, which was previously on-prem only, now works in the cloud. Erik explains why this matters: the snapshot debugger takes periodic snapshots of the call stack (e.g., every 100 milliseconds). If a function executes entirely between two snapshots, it never appears in the profiling data — making it look like the code jumped from function A directly to function C, skipping function B entirely. Being able to adjust the sampling interval helps catch these gaps.

IntelliSense in the Debug Console

When typing in the VS Code debug console during an AL debugging session, you now get IntelliSense — type a record variable name, hit dot, and you get field names. Erik notes the next wish-list item would be full expression evaluation in the debug console.

Default Folder Location for New AL Projects

Instead of always defaulting to the Documents folder, you can now configure the default location for new AL projects — similar to the repository settings in full Visual Studio.

Build Metadata on Extensions

Primarily useful for CI/CD pipelines, you can now embed metadata in your app about the source repository, commit hash, and build system. Erik mentions he plans to integrate this into his ALBuild tooling soon.

Here’s what this looks like in the app.json manifest — though Erik’s sample file doesn’t include these fields, the concept is that you’d add properties like source, repository, commit, buildBy, etc.:

{
  "id": "a200c67e-58ec-4b14-84c9-4f3a621ca557",
  "name": "WhatsNewInBC26",
  "publisher": "Default Publisher",
  "version": "1.0.0.0",
  "platform": "1.0.0.0",
  "application": "26.0.0.0",
  "runtime": "15.0",
  "idRanges": [
    {
      "from": 50100,
      "to": 50149
    }
  ],
  "resourceExposurePolicy": {
    "allowDebugging": true,
    "allowDownloadingSource": true,
    "includeSourceInSymbolFile": true
  },
  "features": [
    "NoImplicitWith"
  ]
}

Secret Text Data Type

A new data type called SecretText prevents credentials and sensitive textual values from being revealed through debugging or logging. If you’re handling passwords, authorization tokens, or API keys, you can now keep them truly secret. Erik flags this as deserving its own dedicated video.

AL Doc Tools for Documentation

The ALDoc tooling for generating documentation from AL code is now available. Erik notes he’s already done a video on this topic.

Namespaces — The Big One

Erik calls this the single most significant change in BC23. Until now, every object in Business Central existed in one giant global scope — which is why the community has dealt with mandatory affixes, prefixes, and naming conflicts between extensions.

With namespaces, you can now define a hierarchical address for your objects. For example:

namespace DefaultPublisher.WhatsNewInBC26;

using Microsoft.Sales.Customer;
using System.Integration;
using Microsoft.Bank.Statement;

This means you could create a table called “Customer” in your own namespace without conflicting with Microsoft’s Customer table, because the fully qualified name would be something like DefaultPublisher.WhatsNewInBC26.Customer.

Erik’s sample code demonstrates the namespace syntax at the top of an AL file, along with using statements to reference objects from other namespaces:

namespace DefaultPublisher.WhatsNewInBC26;

using Microsoft.Sales.Customer;
using System.Integration;
using Microsoft.Bank.Statement;

pageextension 50100 CustomerListExt extends "Customer List"
{
    actions
    {
        addfirst(processing)
        {
            action("Open the bank Statement here Sheryl!")
            {
                RunObject = page "Bank Account Statement";
                ApplicationArea = all;
            }
        }
    }
    trigger OnOpenPage();
    var
        s: Text;
        d: Decimal;
        l: Label 'Hello YouTube';
        da: Date;
        dt: DateTime;
    begin
        s := 'INVOICE1000';
        d := 123.456;
        da := today();
        dt := CurrentDateTime();

        Message('%1 vs %2', d.ToText(), dt.ToText(true), format(dt, 0, 9));
    end;
}

Erik predicts that Microsoft will eventually require namespaces for AppSource submissions — first as a friendly suggestion, then as an enforced requirement. He advises getting ahead of this by adopting namespaces as soon as possible.

Other Notable Items from the Official List

  • AL on Linux: The AL Language extension now works on Linux, since everything runs on .NET Core (now just .NET) and VS Code is cross-platform.
  • Built-in Rich Text Editor: Microsoft’s internal email editor control is now exposed as a property for partner use, though Erik has opinions about how it’s packaged.
  • Turn Off Data Analysis Mode: You can now disable the analysis mode on specific pages — important because it could previously expose fields that weren’t meant to be visible to users.
  • Open Source Code from Web Client: Auto-generates a small project for snapshot debugging and troubleshooting extensions.
  • Add Field Groups to Existing Tables: Table extensions can now add field groups. If the field group doesn’t exist on the base table, it gets created. Erik remains skeptical about the implementation, noting that different lookups to the same table often need different visible columns.
  • Teaching Tips on Queries and Report Request Pages: The teaching tips feature (guided walkthroughs on pages) is now supported on more object types.
  • Syntax Highlighting for AL in Azure DevOps: TextMate grammar support for AL files in Azure DevOps.
  • AppSource Monetization and Preview: ISVs can sell through AppSource with credit card payments and preview apps with select customers — though Erik notes the existing diversity of licensing models makes adoption challenging.

Inside the Compiler: The Hacker Edition Findings

Erik then dives into the decompiled compiler DLL, searching for features tagged with version 12.0 (the runtime version for BC23). He found 49 results. Here are the highlights:

Event Version Attribute

External business events can now have a version attribute, which should help avoid breaking changes when events evolve over time.

Barcode Extended Data Type

The ExtendedDataType property — where you set things like Masked for passwords — now has a new option: Barcode. This presumably allows displaying field values as barcodes on screen.

AllowInCustomization Property

A new property on fields called AllowInCustomization with a “Never” setting. In BC23, personalization allows users to add fields to a page that weren’t originally visible. This property lets developers prevent specific sensitive fields from ever being added through personalization. Erik predicts Microsoft will gradually add AllowInCustomization = Never to many of their own fields after a wave of support calls from users putting inappropriate fields on screen.

AnalysisModeEnabled Property

A new page-level property that controls whether users can use the analysis mode on that specific page. Setting it to false disables the pivot-table-like analysis feature on that page.

Editable as Client-Side Expression

The Editable property on page controls can now be controlled by a client-side Boolean expression — similar to how Visible can already be bound to a Boolean variable. This means dynamic editability without round-trips to the server.

Excel Layout Multiple Data Sheets

Excel report layouts now support multiple data sheets. Previously, all data from all tables was dumped into a single sheet with null columns for non-applicable fields. Now there’s a setting to use separate sheets per data item.

Table Move To / Move From

New properties on tables for MoveTo and MoveFrom, along with obsolete states of “PendingMove” and “Moved.” This appears related to the ability to move tables between extensions — possibly expanding beyond the on-prem-only capability that existed before.

Expanded Secret Text Support

The HTTP client classes (HttpContent, HttpHeaders, HttpRequestMessage) all received new overloads supporting SecretText:

  • HttpContent: Read as SecretText, write from SecretText
  • HttpHeaders: New Add overload with SecretText, TryAddWithoutValidation with SecretText, GetSecretValues, ContainsSecret
  • HttpRequestMessage: SetRequestUri with SecretText
  • Notifications: Add action overloads with descriptions
  • The built-in Clear function gets an overload for SecretText (since AL treats Clear almost like an overloaded system function)

Error Information Enhancements

The ErrorInfo type gets additional overloads for AddAction and AddNavigationAction that now include description parameters alongside captions.

FieldRef Gets IsEnum

The FieldRef type now has an IsEnum method. Erik explains the reasoning: the FieldRef.Type property returns Option for both old-style option fields and modern enum fields. Since changing this would be a breaking change, IsEnum provides a non-breaking way to distinguish between the two.

HTTP Client Additions

Beyond SecretText support, there are new methods including AddCertificate and UseWindowsAuthentication — the latter being particularly interesting for on-prem integration scenarios.

SetBaseLoadFields and IsFieldLoaded

Erik spotted SetBaseLoadFields and what appears to be an IsFieldLoaded function. He’s not entirely sure if these are new or enhanced, but flags them as worth testing.

Variant Supports List and Dictionary

The Variant type now has IsList and IsDictionary methods, meaning you can pass a List or Dictionary through a variant parameter and test for it. Erik notes this is notable because most of the variant type’s capabilities have been unchanged since the early versions of AL.

The WebPageViewer Control Add-in

Erik’s sample code also includes an example of using the WebPageViewer control add-in, which allows embedding web content inside a Business Central page:

page 50100 "test"
{
    PageType = UserControlHost;
    layout
    {
        area(Content)
        {
            usercontrol(web; WebPageViewer)
            {
                trigger ControlAddInReady(CallbackUrl: Text)
                begin
                    this.CurrPage.web.Navigate('https://www.hougaard.com');
                end;
            }
        }
    }
}

Summary and Predictions

BC23 is a substantial release for AL developers. The highlights:

  • Namespaces are the biggest change, fundamentally altering how AL objects are organized and referenced. Erik predicts these will become mandatory for AppSource submissions in the near future.
  • SecretText is pervasive — it touches the HTTP client, headers, content, and even the built-in Clear function.
  • Hidden gems from the decompiler include barcode display support, the AllowInCustomization property, AnalysisModeEnabled, client-side editable expressions, multiple Excel sheets in report layouts, and FieldRef.IsEnum.
  • Developer experience improvements like Find All References on triggers, IntelliSense in the debug console, and improved profiler sampling intervals make the day-to-day development workflow smoother.

As always with these “Hacker Edition” videos, the decompiler reveals that there’s more happening under the hood than the official release notes suggest. Keep an eye out for Erik’s upcoming deep-dive videos on namespaces, SecretText, and the other major features covered here.