---
id: release/al-15.0
type: release
title: AL Language extension 15.0
summary: "AL Language extension 15.0 for Business Central 2025 release wave 1 (BC26): previewed 2024-09-10, released 2025-04-02; 19 changelog entries, 17 GitHub issues linked."
tier: official
language: en
system: development
tags:
  - mocking http calls in al tests
  - httpclienthandler
  - testhttprequestpolicy property
  - example code
  - searchable downloaded symbols and using them as context in copilot chat
  - usercontrolhost pagetype
  - multiline strings
  - continue statement
review:
  state: derived
  by: null
  at: null
  flags: []
generated:
  at: "2026-10-09T15:15:16.913Z"
  pipeline: 0.2.0
  prompts: {}
  input_hash: 14bd1170761b052d4b0559d5421fa19309bf83805cb1b6c321e70c6cfd38498c
evidence:
  - kind: marketplace
    url: https://marketplace.visualstudio.com/items/ms-dynamics-smb.al/changelog
    title: AL Language extension changelog, version 15.0
    date: "2025-04-02"
    commit: null
    t: null
    quote: null
links:
  learn: []
  objects: []
  features: []
  topics: []
  localizations: []
  videos: []
  posts: []
  guidelines: []
source_id: al-language-extension
extension: ms-dynamics-smb.al
version: "15.0"
wave: 2025 release wave 1
major: "26"
preview_at: "2024-09-10"
released_at: "2025-04-02"
published_at: "2025-04-02"
prerelease: false
entry_count: 19
issues:
  - 7746
  - 7769
  - 7787
  - 7801
  - 7846
  - 7873
  - 7880
  - 7898
  - 7924
  - 7963
  - 7964
  - 7965
  - 7968
  - 7969
  - 7974
  - 7979
  - 7981
changes: []
---

# AL Language extension 15.0

> AL Language extension 15.0 for Business Central 2025 release wave 1 (BC26): previewed 2024-09-10, released 2025-04-02; 19 changelog entries, 17 GitHub issues linked.

[Changelog on the Visual Studio Marketplace](https://marketplace.visualstudio.com/items/ms-dynamics-smb.al/changelog) · Business Central 2025 release wave 1 · BC26

## Mocking HTTP calls in AL tests

We have introduced a new handler type `HttpClientHandler` to allow mocking the response of HTTP requests in test codeunits. This feature allows for more controlled and easier testing of modules that interact with external services. The feature is limited to OnPrem instances only.

### HttpClientHandler

When an `HttpClientHandler` is added to a test method, every HTTP request that occurs during the execution of that test will be intercepted and routed to the handler. The handler method signature is as follows: it receives a `TestHttpRequestMessage` that contains information about the HTTP request, as well as a `TestHttpResponseMessage` that contains the mocked HTTP response values that should be updated by the handler. The Boolean return value indicates whether to fall through and issue the original HTTP request (true) or to use the mocked response (false).

### TestHttpRequestPolicy Property

We have also introduced a new property on test codeunits called `TestHttpRequestPolicy`. This property determines how outbound HTTP requests are treated during test execution and has the following possible values:

- **BlockOutboundRequests**: Any HTTP request issued during the test execution that is not caught and handled by an HTTP client handler will raise an exception.
- **AllowOutboundFromHandler**: All HTTP requests issued during the test execution are required to be caught by an HTTP client handler. The handler is allowed to explicitly fall through to issue the original request to the external endpoint.
- **AllowAllOutboundRequests**: All outbound HTTP requests issued during the test execution are allowed.

### Example code

```AL
codeunit 10 MyCodeunit
{
    procedure MethodWithHttpRequest()
    var
        Client: HttpClient;
        Response: HttpResponseMessage;
    begin
        Client.Get('http://example.com/', Response);
    end;
}

codeunit 11 MyCodeunitTests
{
    Subtype = Test;
    TestHttpRequestPolicy = AllowOutboundFromHandler;

    [Test]
    [HandlerFunctions('HttpClientHandler')]
    procedure TestUnauthorizedResponseHandled()
    var
        MyCodeunit: Codeunit "MyCodeunit";
    begin
        MyCodeunit.MethodWithHttpRequest();
    end;

    [HttpClientHandler]
    procedure HttpClientHandler(request: TestHttpRequestMessage; var response: TestHttpResponseMessage): Boolean
    begin
        // Mock a '401 Unauthorized' response for the 'GET http://example.com/' request
        if (request.RequestType = HttpRequestType::Get) and (request.Path = 'http://example.com/') then begin
            response.HttpStatusCode := 401;
            response.ReasonPhrase := 'Unauthorized';
            exit(false); // Use the mocked response
        end;

        // Fall through and issue the original request in case of other requests
        exit(true);
    end;
}
```

## Searchable downloaded symbols and using them as context in Copilot Chat

Objects from downloaded symbol packages can now be added as context when using the Github Copilot Chat extension (prerelease version 0.24.2024121201) and Visual Studio Code Insiders (version 1.97 and later). It will also be possible to search and navigate to objects coming from downloaded symbol packages via the 'Open Symbol by Name' functionality (`Ctrl + T`). Additionally, the performance of searching workspace symbols has been improved to support the now larger amount of available symbols.

## UserControlHost PageType

We have introduced a new PageType `UserControlHost`. This page type can be used to only render a single usercontrol in the client. With the `UserControlHost` page type, the layout is optimized by the client to maximize the available space for the usercontrol.

This new page can **only** have a single control of type `usercontrol` within the layout `Content` area.

Actions cannot be specified on this page, and limited properties and triggers are available for it. It is also not extensible.

## Multiline strings

AL now has support for multiline string literals. A multiline string must be prefixed with @.

```AL
var
    t: Text;
begin
    t := @'This is
a
multiline
string
';
end;
```

## Continue statement

From runtime version 15, it is possible to use the `continue` keyword in loops to continue to the next iteration.

## Preview support in File

Two new methods to open and view a file on the client.

```AL
[Ok :=] File.ViewFromStream(Stream: InStream, FileName: String [, AllowDownloadAndPrint: Boolean]);
[Ok :=] File.View(FilePath: String [, AllowDownloadAndPrint: Boolean]);
```

## New methods access properties and array elements

We have improved the API for accessing JSON data with a new set of methods that will avoid always to read data through a JsonToken.

For JsonObject instances we have added:

```AL
value := GetBoolean(Key: Text [; DefaultIfNotFound: Boolean])
value := GetByte(Key: Text [; DefaultIfNotFound: Boolean])
value := GetChar(Key: Text [; DefaultIfNotFound: Boolean])
value := GetInteger(Key: Text [; DefaultIfNotFound: Boolean])
value := GetBigInteger(Key: Text [; DefaultIfNotFound: Boolean])
value := GetDecimal(Key: Text [; DefaultIfNotFound: Boolean])
value := GetOption(Key: Text [; DefaultIfNotFound: Boolean])
value := GetDateTime(Key: Text [; DefaultIfNotFound: Boolean])
value := GetDate(Key: Text [; DefaultIfNotFound: Boolean])
value := GetTime(Key: Text [; DefaultIfNotFound: Boolean])
value := GetDuration(Key: Text [; DefaultIfNotFound: Boolean])
value := GetText(Key: Text [; DefaultIfNotFound: Boolean])
value := GetArray(Key: Text [; DefaultIfNotFound: Boolean])
value := GetObject(Key: Text [; DefaultIfNotFound: Boolean])
```

For JsonArray instances we have added:
```AL
value := GetBoolean(Index: Integer [; DefaultIfNotFound: Boolean])
value := GetByte(Index: Integer [; DefaultIfNotFound: Boolean])
value := GetChar(Index: Integer [; DefaultIfNotFound: Boolean])
value := GetInteger(Index: Integer [; DefaultIfNotFound: Boolean])
value := GetBigInteger(Index: Integer [; DefaultIfNotFound: Boolean])
value := GetDecimal(Index: Integer [; DefaultIfNotFound: Boolean])
value := GetOption(Index: Integer [; DefaultIfNotFound: Boolean])
value := GetDateTime(Index: Integer [; DefaultIfNotFound: Boolean])
value := GetDate(Index: Integer [; DefaultIfNotFound: Boolean])
value := GetTime(Index: Integer [; DefaultIfNotFound: Boolean])
value := GetDuration(Index: Integer [; DefaultIfNotFound: Boolean])
value := GetText(Index: Integer [; DefaultIfNotFound: Boolean])
value := GetArray(Index: Integer [; DefaultIfNotFound: Boolean])
value := GetObject(Index: Integer [; DefaultIfNtFound: Boolean])       o
```

## New Command in VSCode to start a new project from a template

We have added a new command AL.NewProject. From this it is possible to start a new project from a template.

## New IncStr method overload

A new overload of the `IncStr` method was added to support an arbitrary positive increment. This allows for incrementing number series or other similar series by more than one position in one go.

## New VS Code actions from the Web Client

Two new actions have been added to the **Extension Management** page. One to generate launch configurations in your local AL project to match the environment, and another to select installed extensions and download them as dependencies.

## GitHub Issues

- [#7787](https://github.com/microsoft/AL/issues/7787) Rule AA0234 implemented inconsistently?
- Added warning [AL0864](https://learn.microsoft.com/dynamics365/business-central/dev-itpro/developer/diagnostics/diagnostic-al864) when having controls of `ChartPart` type, since they are not supported by the web client. From runtime version 16.0, this will turn into the error [AL0855](https://learn.microsoft.com/dynamics365/business-central/dev-itpro/developer/diagnostics/diagnostic-al865).
- [#7746](https://github.com/microsoft/AL/issues/7746) Misleading ToolTip on RunTime in App.Json
- [#7873](https://github.com/microsoft/AL/issues/7873) False positives for warning AA0234
- [#7880](https://github.com/microsoft/AL/issues/7880) Interface XML comments are not properly handled. They are ignored
- [#7898](https://github.com/microsoft/AL/issues/7898) AA0205 is fired for assigned variables when combined with THIS keyword
- [#7846](https://github.com/microsoft/AL/issues/7846) Wrong tooltip in TableRelation when table name matches top-level namespace name
- [#7924](https://github.com/microsoft/AL/issues/7924) AA0242 is thrown when "Rec.AddLoadFields" is used after "Rec.SetLoadFields"
- [#7769](https://github.com/microsoft/AL/issues/7769) The AL Server crashed 5 times in the last 3 minutes
- [#7801](https://github.com/microsoft/AL/issues/7801) AA0218 not working as expected for dependent fields
- [#7965](https://github.com/microsoft/AL/issues/7965) ALDoc - Referenced module not loaded. Name:'Application'
- [#7968](https://github.com/microsoft/AL/issues/7968) AS0064 is thrown even if interface is Access=Internal
- [#7963](https://github.com/microsoft/AL/issues/7963) The AL compiler builds invalid permission XML files when it contains only few permissions
- [#7969](https://github.com/microsoft/AL/issues/7969) Missing AL0185 for page parts
- [#7964](https://github.com/microsoft/AL/issues/7964) Error AS0003 when compiling any app with AppSourceCop enabled - MacOS
- [#7974](https://github.com/microsoft/AL/issues/7974) InlayHint fails
- [#7979](https://github.com/microsoft/AL/issues/7979) ALDoc skips documentations for objects with ampersand
- [#7885](https://github.com/microsoft/AL/issues/7979) No object ID suggested when namespace is used
- [#7981](https://github.com/microsoft/AL/issues/7981) ALDoc skips documentation if procedure param record has ampersand

## AppSourceCop

- Updated rule [AS0128](https://learn.microsoft.com/dynamics365/business-central/dev-itpro/developer/analyzers/appsourcecop-as0128) to allow removing a previously obsoleted interface from the list of extended interfaces.
- New rule [AS0130](https://learn.microsoft.com/dynamics365/business-central/dev-itpro/developer/analyzers/appsourcecop-as0130) that warns against duplicate object names across namespaces.
- Updated rule [AS0064](https://learn.microsoft.com/dynamics365/business-central/dev-itpro/developer/analyzers/appsourcecop-as0064) to allow removing a previously internal interface from the list of implemented interfaces.

## PerTenantExtensionCop rules

- New rule [PTE0025](https://learn.microsoft.com/dynamics365/business-central/dev-itpro/developer/analyzers/pertenantextensioncop-pte0025) that warns against duplicate object names across namespaces.

## Reporting

- Added the `ObsoleteState`, `ObsoleteReason`, and `ObsoleteTag` properties to the Report Layout to enable marking a layout as obsolete.
- Added the `ExcelLayoutMultipleDataSheets` property to the Report Layout to specify whether an Excel layout should be rendered with multiple or a single data sheet.
- Add new Excel data sheet when adding root level data items and the layout uses multiple data sheets.
- Add new layout information fields in the aggregated metadata sheet for the Excel layout template (layout name, caption and id). Also add Company Display name to the same table.
- Add a new report trigger OnPreRendering to handle additional platform processing of the generated report artifact.
- Add a new report property TargetFormat that gets the current output format.
- Fixed a problem with multiple sheet Microsoft Excel layout generation, when root DataItems had names containing special or whitespace characters (Excel required table repairs before the workbook could open).

## HttpClient

- Added the `UseServerCertificateValidation` property to the HttpClient data type to selectively disable server certificate validation on HTTP requests. Default value is true.

## Miscellaneous

- Added SetAutoCalcFields on the RecordRef data type.
- Deprecated Debugger.EnableSqlTrace
- When the `AddText` or `Read` methods are used on a non-assignable target of type `BigText`, the produced values will be discarded instead of causing a crash.
- Interfaces cannot contain methods whose signatures collide with the methods from the extended interfaces. It is also not possible to extend an interface with other interfaces whose methods collide.
- Allow having a dictionary where the value type is an interface.
- [BCIdea](https://experience.dynamics.com/ideas/idea/?ideaid=6392e5fb-bf39-ed11-97b1-0003ff45a617) Hovering over labels will additionally reveal if they are locked. Enums will show ordinal values. Codeunit hover text will contain the subtype (if it is a test or install codeunit etc.) and if it is a single instance.
- [BCIdea](https://experience.dynamics.com/ideas/idea/?ideaid=db0e5a74-25c0-e911-b083-0003ff68d32d) Support modification of `CardPageID` on `PageExtension`s. If the property is already specified on the base page, the value in the `PageExtension` will override it. If multiple `PageExtension`s modify the property, the last extension to be applied will take effect.
- [BCIdea](https://experience.dynamics.com/ideas/idea/?ideaid=29cf8e3d-8dfd-ea11-b5d9-0003ff688ba0) Added ToText method to simple types (BigInteger, Boolean, Byte, Date, DateTime, Decimal, Duration, Guid, Integer, Time, Version) for simple conversion to text. Continue to use FORMAT for advanced formatting options.
- Added a new ValidateServerCertificate property in the launch.json file. Default value is true. When set to false the connection to the Business Central service will no longer validate the server endpoint certificate.
- [BCIdea](https://experience.dynamics.com/ideas/idea/?ideaid=ef198658-bf39-ed11-97b1-0003ff45a617) It is now possible to 'Peek references' by clicking CodeLenses
- [CodeLens references](https://raw.githubusercontent.com/microsoft/AL/master/resources/CodeLensReferences.gif)
- OptimizeForTextSearch will now cause an error if used on non-normal tables or fields.
- Fixed an issue with "Publish Full Dependency For Active Project" where publishing would fail to use the correct port if a port was specified in the server URL in the `launch.json` file.
- Fixed an issue where moved fields would cause an ambiguous reference error when used in TestFilters.
- When autocompleting overloads for methods, if all of them have the same deprecation reason, the description will contain it.
- Fixed issues with the "Implement Interface" codefixer. Methods with interfaces parameters are generated correctly. Variable/Parameters type casing is aligned to Pascal Case. Fully qualified names are only used if needed i.e. respecting namespace-declaration and using-statements.
- Fixed issue with deep structured code would cause StackOverflowException
- Added support to display the default value of boolean properties on hover and in IntelliSense suggestions.
- Actions that have the `RunObject` property specified will use the [Caption](https://learn.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/properties/devenv-caption-property), [ToolTip](https://learn.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/properties/devenv-tooltip-property), [AboutText](https://learn.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/properties/devenv-abouttext-property), and [AboutTitle](https://learn.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/properties/devenv-abouttitle-property) properties of the targeted application object if none of these properties are specified. In support of this, the ToolTip property has also been added to Reports.
- It is now possible to specify layout on the GetUrl command.
- Fixed an issue where object IDs were not recommended with namespaces.
- Added support for getting the current callstack by using the following statement `callstack := SessionInformation.Callstack`.
- Fixed an issue where Rapid Application Development (RAD) publishing would break when workspace changes consisted only of deleted files.
- Continue keyword is now recommended by intellisense.
- New CodeCop rule [AA0249](https://learn.microsoft.com/dynamics365/business-central/dev-itpro/developer/analyzers/codecop-aa0249) to warn about unused page field triggers.

Source: Visual Studio Marketplace, ms-dynamics-smb.al changelog, Microsoft's text unchanged. Dates from the gallery's upload records.
