alcraftalcraft
alcraft / Technical / AL Development Kennisbank
AL Development BC27

Type Helper (Codeunit 10): praktijkgids en BC26/BC27-migratie

door Rodney · · 7 min leestijd
Op deze pagina
  1. Wat is de Type Helper
  2. Wat verandert in BC26: twee taalhelpers worden obsolete
  3. LanguageIDToCultureName
  4. GetCultureName
  5. Wat verandert in BC27: UrlEncodeSecret wordt obsolete
  6. Migratiestappenplan
  7. Stap 1 — Inventariseer gebruik van obsolete procedures
  8. Stap 2 — Migreer LanguageIDToCultureName
  9. Stap 3 — Migreer TypeHelper.GetCultureName
  10. Stap 4 — Migreer UrlEncodeSecret
  11. Stap 5 — Controleer op compiler-waarschuwingen
  12. Procedures die je écht gebruikt
  13. Strings
  14. Datum en tijd
  15. URL en encoding
  16. Recordreflectie
  17. Procedures die de meeste developers niet kennen
  18. BitwiseAnd, BitwiseOr, BitwiseXor
  19. TestFieldIsNotObsolete
  20. JavaScriptStringEncode
  21. OptionsAreEqual
  22. GetMaxNumberOfParametersInSQLQuery
  23. Bekende valkuil: ConvertDateTimeFromUTCToTimeZone
  24. Veelgestelde vragen
  25. Wat is Codeunit 10 Type Helper in Business Central?
  26. Welke Type Helper procedures zijn obsolete in BC26?
  27. Hoe vervang ik LanguageIDToCultureName?
  28. Wat is het verschil tussen UrlEncode en UrlEncodeSecret?
  29. Kan ik ConvertDateTimeFromUTCToTimeZone vertrouwen voor UTC-conversies?

TL;DR — Codeunit 10 Type Helper (namespace System.Reflection) bevat ruim 60 utility-procedures voor strings, datums, URL-codering, veldinspectie en bitwise-operaties. Op BC26 zijn LanguageIDToCultureName en GetCultureName obsolete — gebruik Codeunit 43 Language als vervanging. Op BC27 is UrlEncodeSecret verouderd; gebruik de SecretText-overload van UrlEncode. Drie concrete migratiepunten voor bestaande extensies. Bijkomend nuttig en weinig bekend: BitwiseAnd, TestFieldIsNotObsolete en JavaScriptStringEncode. Geverifieerd op BC27.

Wat is de Type Helper

Codeunit "Type Helper" (ID 10, namespace System.Reflection) bestaat al zo lang als Business Central. De codeunit bundelt utility-procedures die je anders zelf zou moeten schrijven: is dit tekst een getal, hoeveel Levenshtein-afstand zit er tussen twee strings, geef me de huidige UTC-tijd in ISO 8601-formaat, codeer deze waarde voor een URL.

Je declareert hem als een gewone variabele:

var
    TypeHelper: Codeunit "Type Helper";

De codeunit heeft InherentEntitlements: X en InherentPermissions: X, wat betekent dat hij werkt zonder expliciete toegewezen rechten. Op BC27 bevat hij meer dan 60 procedures, verspreid over categorieën als strings, datum/tijd, timezone, URL-codering, veld- en recordreflectie, en bitwise-operaties.

Wat verandert in BC26: twee taalhelpers worden obsolete

BC26 (Business Central 2025 wave 1, uitgebracht april 2025) markeert twee procedures als [Obsolete(..., '26.0')]:

LanguageIDToCultureName

// Obsolete: gebruik dit niet meer op BC26+
procedure LanguageIDToCultureName(LanguageID: Integer): Text

Vervanging: Codeunit 43 Language, procedure GetCultureName(LanguageID).

// Oud
var
    TypeHelper: Codeunit "Type Helper";
    CultureName: Text;
begin
    CultureName := TypeHelper.LanguageIDToCultureName(1043); // 'nl-NL'
end;

// Nieuw
var
    Language: Codeunit Language;
    CultureName: Text;
begin
    CultureName := Language.GetCultureName(1043); // 'nl-NL'
end;

GetCultureName

// Obsolete: gebruik dit niet meer op BC26+
procedure GetCultureName(): Text

Vervanging: Codeunit 43 Language, procedure GetCurrentCultureName().

// Oud
var
    TypeHelper: Codeunit "Type Helper";
    CultureName: Text;
begin
    CultureName := TypeHelper.GetCultureName();
end;

// Nieuw
var
    Language: Codeunit Language;
    CultureName: Text;
begin
    CultureName := Language.GetCurrentCultureName();
end;

Let op het naamverschil: in Codeunit 43 heet de parameterloze versie GetCurrentCultureName, niet GetCultureName. GetCultureName in Codeunit 43 is de versie mét LanguageID-parameter.

Wat verandert in BC27: UrlEncodeSecret wordt obsolete

BC27 (Business Central 2025 wave 2, uitgebracht oktober 2025) markeert UrlEncodeSecret als [Obsolete(..., '27.0')]:

// Obsolete: gebruik dit niet meer op BC27+
[NonDebuggable]
procedure UrlEncodeSecret(var Value: Text): Text

De vervanging is de bestaande UrlEncode-overload die een SecretText accepteert:

[NonDebuggable]
procedure UrlEncode(var Value: SecretText): SecretText

Migratie:

// Oud — UrlEncodeSecret met platte Text
var
    TypeHelper: Codeunit "Type Helper";
    ApiKey: Text;
    Encoded: Text;
begin
    ApiKey := 'mijn-geheime-sleutel';
    Encoded := TypeHelper.UrlEncodeSecret(ApiKey);
end;

// Nieuw — UrlEncode met SecretText
var
    TypeHelper: Codeunit "Type Helper";
    ApiKey: SecretText;
    Encoded: SecretText;
begin
    ApiKey := 'mijn-geheime-sleutel';
    Encoded := TypeHelper.UrlEncode(ApiKey);
end;

Het type van de variabele verandert van Text naar SecretText. Daardoor verdwijnt de waarde uit de AL debugger en uit telemetrie-logs — precies wat je wil bij API-sleutels en wachtwoorden.

Migratiestappenplan

(De stappen hieronder corresponderen met de HowTo-data in de frontmatter en worden in JSON-LD geëxporteerd.)

Stap 1 — Inventariseer gebruik van obsolete procedures

Zoek in je extensie op de drie namen. In VS Code met de AL Language Extension:

LanguageIDToCultureName
GetCultureName
UrlEncodeSecret

Controleer elk treffer: roep je het aan via een Codeunit "Type Helper"-variabele? Dan moet het gemigreerd worden.

Stap 2 — Migreer LanguageIDToCultureName

Voeg Codeunit Language als variabele toe. Vervang TypeHelper.LanguageIDToCultureName(Id) door Language.GetCultureName(Id).

Stap 3 — Migreer TypeHelper.GetCultureName

Vervang TypeHelper.GetCultureName() door Language.GetCurrentCultureName(). Niet Language.GetCultureName() — dat is de overload met LanguageID-parameter.

Stap 4 — Migreer UrlEncodeSecret

Verander het type van de te coderen waarde van Text naar SecretText. De rest van de aanroep blijft hetzelfde (TypeHelper.UrlEncode(waarde)).

Stap 5 — Controleer op compiler-waarschuwingen

Herbouw de extensie. Compiler-waarschuwing AL0432 (“Member is obsolete”) verdwijnt als alle drie de procedures zijn gemigreerd.

Procedures die je écht gebruikt

Strings

IsNumeric — valideert of tekst als Decimal te lezen is:

if TypeHelper.IsNumeric(InputText) then
    Value := InputText.ToDecimal();

TextDistance — berekent de afstand tussen twee strings. Handig voor fuzzy matching, suggesties en foutdetectie. Er geldt een praktische limiet van ~1024 tekens.

NewLine / CRLFSeparator / LFSeparator — retourneren de correcte regeleinde-tekens voor het huidige platform. Gebruik dit in plaats van hard-coded #13#10 of #10:

Message := 'Eerste regel' + TypeHelper.NewLine() + 'Tweede regel';

Datum en tijd

CompareDateTime — vergelijkt twee DateTime-waarden en retourneert 1, 0 of -1, waarbij rekening gehouden wordt met de precisie van SQL Server (milliseconden). Veiliger dan directe =-vergelijking op DateTime.

GetHMSFromTime — haalt uur, minuut en seconde uit een Time-waarde via out-parameters:

var
    Hour, Minute, Second: Integer;
begin
    TypeHelper.GetHMSFromTime(Hour, Minute, Second, Time());
end;

GetCurrUTCDateTimeISO8601 — retourneert de huidige UTC-tijd als ISO 8601-tekst (2026-04-30T14:23:00Z). Direct bruikbaar in REST-API-payloads.

EvaluateUnixTimestamp — converteert een Unix-epoch (BigInteger) naar een BC DateTime:

var
    EventTime: DateTime;
begin
    EventTime := TypeHelper.EvaluateUnixTimestamp(1745000000);
end;

URL en encoding

UrlEncode / UrlDecode — standaard URL-codering. De SecretText-overload (BC27+) is de juiste keuze voor gevoelige waarden.

UriEscapeDataString — percent-codeert een waarde conform RFC 3986. Gebruik dit voor query-parameter-waarden in REST-API-calls:

EncodedParam := TypeHelper.UriEscapeDataString(CustomerName);
Url := 'https://api.example.com/customers?name=' + EncodedParam;

Het verschil met UrlEncode: UriEscapeDataString codeert ook + en /, wat correct is voor parameterwaarden. UrlEncode is historisch wat losser met de spec.

HtmlEncode / HtmlDecode — voor veilige output in HTML-context. Codeert <, >, & en soortgelijke tekens.

Recordreflectie

GetField — haalt een Field-record op via tabel- en veldnummer, retourneert false als het veld niet bestaat of als obsolete is gemarkeerd.

SortRecordRef — past een sortering toe op een RecordRef via komma-gescheiden veldnamen. Handig in generieke export- of verwerkingscode.

GetKeyAsString — retourneert de primaire sleutelvelden van een record als komma-gescheiden tekst. Goed voor logging:

LogEntry."Record Key" := TypeHelper.GetKeyAsString(SalesHeader, 1);

Procedures die de meeste developers niet kennen

BitwiseAnd, BitwiseOr, BitwiseXor

AL heeft geen native bitwise-operatoren. Type Helper vult dat gat:

var
    Flags: Integer;
    Mask: Integer;
begin
    Flags := TypeHelper.BitwiseOr(Flags, 4);   // zet bit 2
    if TypeHelper.BitwiseAnd(Flags, 4) = 4 then // test bit 2
        ...
    Flags := TypeHelper.BitwiseXor(Flags, 4);   // toggle bit 2
end;

Nuttig als je met externe systemen werkt die status- of permissievelden als bitflags opslaan.

TestFieldIsNotObsolete

procedure TestFieldIsNotObsolete(Field: Record Field)

Gooit een runtime-error als het meegegeven veld de ObsoleteState = Removed heeft. Gebruik dit in generieke code die dynamisch over velden itereert (migratie-tooling, export-frameworks) om stille fouten te voorkomen.

JavaScriptStringEncode

procedure JavaScriptStringEncode(Value: Text): Text
procedure JavaScriptStringEncode(Value: Text, AddDoubleQuotes: Boolean): Text

Escapet een tekst voor gebruik in een JavaScript-string-literal. De tweede overload wikkelt het resultaat optioneel in aanhalingstekens. Nuttig bij het genereren van JavaScript-snippers vanuit AL.

OptionsAreEqual

procedure OptionsAreEqual(Value: Text, CurrentOption: Text): Boolean

Case-insensitieve vergelijking van optie-teksten. Voorkomt de bug waarbij 'Posted' = 'posted' false retourneert in AL.

GetMaxNumberOfParametersInSQLQuery

procedure GetMaxNumberOfParametersInSQLQuery(): Integer

Retourneert het maximum aantal SQL-parameters dat in één query gebruikt mag worden (doorgaans 2100 voor SQL Server). Onmisbaar als je dynamisch een IN-clausule opbouwt via SetFilter met veel waarden: splits de set op als deze het maximum nadert.

Bekende valkuil: ConvertDateTimeFromUTCToTimeZone

De naam suggereert dat je UTC invoert en een lokale tijd terugkrijgt. Dat klopt niet. Microsoft Learn documenteert zelf:

“NOTE: The procedure’s name is incorrect. This procedure converts the time from current client timezone to target timezone, instead of converting from utc to target time zone.”

Gebruik GetTimezoneOffset of GetUserTimezoneOffset als je UTC wil omzetten naar een specifieke tijdzone, en bouw de conversie zelf op basis van de teruggegeven Duration.

Veelgestelde vragen

(De Q&A hieronder wordt ook als FAQPage JSON-LD geëxporteerd, zodat AI-agents en zoekmachines de antwoorden direct kunnen citeren.)

Wat is Codeunit 10 Type Helper in Business Central?

Codeunit "Type Helper" (ID 10, namespace System.Reflection) is een utility-codeunit in de base application met meer dan 60 procedures voor veelvoorkomend werk: strings valideren, datums formatteren, URL-codering, veldinspectie en bitwise-operaties. Je gebruikt hem door een variabele van het type Codeunit "Type Helper" te declareren.

Welke Type Helper procedures zijn obsolete in BC26?

In BC26 (Business Central 2025 wave 1) zijn LanguageIDToCultureName en GetCultureName als obsolete gemarkeerd. Beide worden vervangen door procedures in Codeunit 43 Language: respectievelijk Language.GetCultureName(LanguageId) en Language.GetCurrentCultureName().

Hoe vervang ik LanguageIDToCultureName?

Declareer een variabele Language van het type Codeunit Language (ID 43). Vervang TypeHelper.LanguageIDToCultureName(LanguageId) door Language.GetCultureName(LanguageId). De signatuur en returnwaarde (Text) zijn identiek.

Wat is het verschil tussen UrlEncode en UrlEncodeSecret?

UrlEncodeSecret (obsolete vanaf BC27) accepteerde een Text-parameter. De vervanging is de SecretText-overload van UrlEncode: die accepteert een SecretText en retourneert een SecretText, zodat de waarde nooit in logs of de debugger verschijnt.

Kan ik ConvertDateTimeFromUTCToTimeZone vertrouwen voor UTC-conversies?

Nee. De naam is misleidend — Microsoft’s eigen documentatie vermeldt dat de procedure de input behandelt als de huidige client-timezone, niet als UTC. Gebruik GetTimezoneOffset of GetUserTimezoneOffset voor correcte UTC-conversies.

Fact-check

Geverifieerd op
30 april 2026
Volgende review
30 april 2027
Bronnen
Reproduceerbaar bewijs
Obsolete-markeringen geverifieerd via Microsoft Learn-documentatie.