MB-820 cheat sheet
MB-820 · Keep the key ideas within reach.
Describe Business Central
Business Central is the Dynamics 365 ERP product; the same AL base application is delivered as Microsoft-hosted SaaS, as an on-premises server installation, and as Docker containers.
Editions: Essentials covers financials, sales, purchasing, inventory, and projects; Premium adds manufacturing and service management on the same platform.
Extension types are AppSource apps (global, Microsoft-validated, distributable) and per-tenant extensions (PTE, uploaded privately and scoped to one tenant).
AL is the only development language; source compiles into .app extension packages and the base application itself is shipped as AL apps.
Environments are Production or Sandbox; sandboxes can be created, copied, reset, and deleted from the admin center and are the only place cloud debugging is allowed.
Admin center URL pattern is businesscentral.dynamics.com//admin, where environments, installed extensions, telemetry, and capacity are managed.
Authentication uses Microsoft Entra ID; data access is granted through permission sets assigned to users, and licensing limits which objects a user can reach.
Telemetry is emitted to Azure Application Insights per environment and covers errors, long-running SQL, and custom trace messages from AL.
A tenant holds multiple environments, and each environment holds one or more companies; records are always scoped to a company unless the table is shared.
Install, develop, and deploy for Business Central
Prerequisites are Visual Studio Code, the AL Language extension, and a reachable Business Central environment (cloud sandbox or container) to download symbols from.
"AL: Go!" scaffolds a project containing app.json, launch.json, and an initial .al file; the target platform version chosen there sets the default runtime.
app.json requires a stable GUID id, name, publisher, version, and idRanges; entries in the dependencies array need id, name, publisher, and version of each dependent app.
The application property sets the minimum Business Central application version and platform sets the minimum runtime version; the target environment must satisfy both.
idRanges must not overlap the base application, Microsoft apps, or other installed extensions; custom code typically uses 50000-99999.
AL: Download Symbols writes .app symbol packages into .alpackages; compilation fails if symbols for the target application version are missing.
launch.json keys include server, serverInstance, environmentName, authentication (AAD, Windows, UserPassword, NavUserPassword), port, and startupObjectId.
AL: Publish compiles, uploads, synchronizes schema, and installs the extension; production deployment builds the .app and uploads it through the admin center.
Online schema synchronization is non-destructive: dropping fields or changing field types fails at publish time, so schema evolution must stay backward compatible.
Develop by using AL objects
Object kinds include table, tableextension, page, pageextension, codeunit, report, reportextension, query, xmlport, enum, enumextension, interface, permissionset, profile, and controladdin.
A table consists of fields, keys (the primary key defines record uniqueness), fieldgroups (Brick, DropDown, Duplicate), and SumIndexFields on keys.
FlowFields are computed at runtime; CalcFormula supports Sum, Count, Average, Min, Max, Lookup, and Exist, and FlowFilters restrict the calculation.
TableType values are Normal, Temporary (session-scoped, never persisted to the database), CRM, ExternalSQL, and Exchange.
PageType values include Card, List, Document, Worksheet, ListPart, CardPart, RoleCenter, API, ConfirmationDialog, and StandardDialog.
A pageextension modifies an existing page through layout, actions, and views blocks using addfirst, addlast, addbefore, addafter, modify, movefirst, and moveafter against named controls.
Extend an enum with an enumextension, and the original enum must declare Extensible = true or the extension is rejected.
ObsoleteState (Pending or Removed), ObsoleteReason, and ObsoleteTag retire objects and fields without deleting them, preserving upgrade paths.
DataClassification must be set on every table field; values include CustomerContent, EndUserIdentifiableInformation, SystemMetadata, and ToDo.
Develop by using AL
Table triggers are OnInsert, OnModify, OnDelete, and OnRename; field-level logic goes in OnValidate and OnLookup; pages use OnAction; codeunits and reports use OnRun.
Lookup methods return Boolean (Find, FindFirst, FindLast, FindSet) while Get raises an error when no record matches; filters are set with SetRange, SetFilter, SetCurrentKey, and SetAscending.
Calling SetLoadFields before a Find retrieves a partial record, loading only the listed fields; other fields are fetched on first access.
Rec holds the current field values and xRec holds the values as last read from or written to the database, which is what OnModify comparisons rely on.
Insert(true), Modify(true), and Delete(true) execute the matching triggers; passing false suppresses them during bulk operations.
AL has no try/catch: Codeunit.Run returns false if an error occurs before any commit inside the called codeunit, but an error after a Commit propagates to the caller.
Publishers use [IntegrationEvent] (internal or external subscribers) and [BusinessEvent]; subscribers declare [EventSubscriber] with the object type, object name, event name, and element name.
The IsHandled pattern passes a Boolean by reference; the subscriber sets it to true and the publisher skips its default logic.
Filter syntax: '..' is a range, '|' is OR, '*' and '?' are wildcards, '@' makes the comparison case-insensitive, and '<>' means not equal.
Work with development tools
Visual Studio Code with the AL Language extension is the full toolchain: Go!, symbol download, build, publish, and the debugger all come from it.
Breakpoints are set in .al files before launching the configuration in launch.json; the debugger attaches to the session started by the publish task.
Cloud debugging and snapshot debugging are available only on Sandbox environments; production environments reject debugger attachment.
Snapshot debugging records a session's execution for later inspection (call stack, variables, breakpoints) and is started from VS Code or the admin center.
Analyzers run at compile time: CodeCop (on by default), UICop, AppSourceCop, and PerTenantExtensionCop; rules and severities are configured through app.json settings or a ruleset file.
The AL Profiler samples statement execution and shows the call tree with timings, which exposes slow loops and excessive database round trips.
AL: Rename (F2) refactors an identifier across the whole project; AL: Download Source retrieves base application source when it is available to the tenant.
Test codeunits contain [Test] procedures executed by the test runner; tests should run against a sandbox or container, never live production data.
The BcContainerHelper PowerShell module creates Docker-based Business Central containers used for local development, automated tests, and CI pipelines.
Integrate Business Central with other applications
API pages (PageType = API) require APIPublisher, APIGroup, APIVersion, EntityName, and EntitySetName, and are addressed at /api////.
API pages use OData V4 and support $filter, $select, $expand, $top, and $batch; the page's source table key determines the entity's unique identifier.
Pages, codeunits, and queries can be published as OData V4 or SOAP web services from the Web Services page; each published object gets a service name and URL.
An exposed query provides a read-only OData feed over joined tables, which consumers query directly without custom API code.
Outbound integration uses the HttpClient type together with JsonObject, JsonArray, and JsonValue to call and parse external REST endpoints.
Token acquisition for outbound OAuth2 calls uses the OAuth2 codeunit with client credentials or authorization code flows; secrets belong in isolated storage or setup, never in code.
Business events published with the BusinessEvent attribute can be subscribed to externally through Azure Service Bus, Event Grid, or Power Automate.
Throttling returns HTTP 429 with a Retry-After header; honoring it and batching requests reduces the number of calls counted against limits.
Control add-ins host JavaScript in the client for UI-level integration only; server-side calls belong in AL on the service tier.