27 June 2024

Mandatory Fields in Dynamics 365 Business Central: 4 Powerful Techniques to Bulletproof Your Data

Picture a finance manager opening the customer list and finding 60 records without payment terms. Payment Terms Code carries a red asterisk on the Customer Card, so everyone assumed it was required. The asterisk marked the field. Nothing stopped anyone from saving without it, so nobody filled it in.

This article is about that gap. Marking a field and enforcing a field are two different mechanisms, and the platform gives you four of them with very different reach. Below: what each one does, the places where required fields quietly stop working, and how to test whether your rule holds.

What "mandatory" means in Business Central

Microsoft is explicit about the asterisk. Its help page on entering data says: "Although a field is mandatory, you aren't required to fill in the field before you continue to other fields or close the page. The red asterisk only serves as a reminder that you'll be blocked from completing a certain process."

The asterisk is a signal about a process. On the Customer Card it appears on Name, Payment Terms Code and the posting group fields, and in the US version also on Tax Area Code. On the Item Card it appears on Description, Base Unit of Measure and the posting groups. The record saves while those fields are empty.

The marking and the enforcement happen at two different moments:

  • Entry time: when a user creates or edits the record.
  • Process time: when someone posts, releases or ships something that uses the record.
Marked at entry, enforced at posting: the record is incomplete and already in use in between.

Standard Business Central puts nearly all of its enforcement at process time. If your requirement is "this field must never be empty," you have to add the enforcement at entry time yourself.

Four ways to make a field mandatory

1. ShowMandatory: the asterisk, and nothing else

ShowMandatory applies to page fields only. Microsoft's documentation is blunt about what it does: the field "is marked on the page with a red asterisk and does not enforce any validation," and "the user will be able to close a page without entering data." It also overrides any asterisk that NotBlank would have produced.

It accepts an expression, which is how Business Central handles Vendor Invoice No. on the Purchase Invoice page: the asterisk follows the Ext. Doc. No. Mandatory setting in Purchases & Payables Setup.

Two limits are worth knowing before you build on it. Number fields with a default value count as already filled, so no asterisk appears. Microsoft's own example is Credit Limit (LCY), where an expression like Credit Limit (LCY) < 5000 produces no asterisk because the field already holds a value. And the property can't validate an AL method, so anything beyond a simple expression is out of reach.

It's a good way to guide a user, and no guarantee that the field gets filled.

2. NotBlank: real validation, narrow scope

NotBlank applies to table fields and page fields, and it does raise an error. It only does so under specific conditions.

The red asterisk only appears when you set it on a primary key field. On any other field there is no visual marking at all. And on non-primary fields the behavior is asymmetric: if the field is blank and was never entered, the page closes without complaint. Only when a user enters a value and then tries to blank it out does the validation error fire.

The second condition has a bigger impact. Microsoft states: "Validation occurs only if the field or control value is updated through the UI... If a field is updated through application code, then the NotBlank property is not validated."

So NotBlank protects a value that already exists against being wiped. It does not make anyone fill the field in the first place, and it does nothing for records filled in by code.

3. TestField: where Business Central actually enforces

TestField is the method the standard application leans on. Called without a value parameter, it raises an error when the field is zero or blank. The runtime adds a Show button to the error dialog, so the user can jump straight to the record that's missing data.

Where you place the call decides what you're protecting:

  • In the table's OnInsert and OnModify triggers, it stops the record from being created or saved incomplete.
  • In the posting or release codeunit, it stops the transaction while leaving the incomplete record in place.

In a table trigger, TestField covers paths the page properties miss, such as Edit in Excel and API calls. Code that writes a record without running the table triggers still skips it. The price is an AL extension: development, deployment, a regression test after every Business Central update, and a new round of code every time the rule needs a condition such as "required for foreign vendors, optional for domestic ones."

4. Configurable rules with the Field Validation app

The fourth route moves the rule out of code and into setup. 2-Controlware's Compliance Field Validation app, available on Microsoft Marketplace, lets you set up validation rules per table and field on a Field Validation card, without custom development.

A Field Validation rule on the Item table: two mandatory fields and two filters, with an init value, a condition and an action after validation.

What that gives you in practice:

  • Seven rule types per line: Mandatory, Filter, Length, Related No. of records, Related Field, Regular Expression and Calculated. "Must not be empty" is one option among several, and a field that must be over 100, a certain length, or match a regular expression takes the same amount of setup.
  • A choice between Warning and Error per validation. With a warning the user sees the message and can continue. With an error the user can't proceed until the value is corrected. In code you would have to build that distinction yourself.
  • Action after Validation, available with warnings: if the record doesn't meet the rules, the app performs an action anyway, such as setting the item card back to Blocked. The user can keep working, but the item stays blocked until the data is complete.
  • Conditions that decide when the rule fires, for example only when a card is unblocked or a document is released. That way the rule doesn't interrupt someone who is still drafting a record.
  • An Insert Check toggle that runs the validations on the table's OnInsert trigger, so the rule applies when the record is created.
  • Validation across related tables, such as requiring at least one valid sales price on a customer, or checking that the Customer Posting Group on a sales order matches the customer card.
  • Rules scoped per company or per permission set, so they apply to one group of users and not another.
  • Default dimension validation, and initial values on insert so a new record starts in a known state, for example blocked.
  • Start and end dates per validation, so you can phase a rule in without breaking today's work.
The Field Validation Results page for item 1969-W: which fields fail which rule, and the action the app takes.

The app comes with a set of default table relations and runs on both the Essential and Premium editions. It has a 30-day free trial, which starts when you register the app in Business Central. The installation walkthrough for Business Central Cloud covers the setup step by step, and the Field Validation documentation has the full field reference.

If you're weighing this against writing the checks yourself, the trade-offs between table validation, codeunits and event subscribers are laid out in our post on effective ways to validate fields in Business Central.

What each technique stops

Technique Shows red asterisk Blocks saving the record Blocks posting or release Runs on the table trigger, not the page Conditional rules without AL
ShowMandatory Yes No No No, page fields only Simple expressions only
NotBlank Primary key fields only Only when a filled value is cleared No No, skipped when a field is set by code No
TestField in triggers No Yes Yes, if also called in the posting code Yes, wherever you place the call No, every condition is code
Field Validation app Uses warning and error messages Yes, with validation type Error Yes, with an Error rule conditioned on release Yes, with Insert Check on the OnInsert trigger Yes

Where mandatory fields quietly fail

Which rule sees which entry path: page rules only see the page they are set on, a rule in the table trigger follows the record.

Records created by code and integrations. Job queues and other extensions write records through code, and nothing you set on a page applies to that traffic. Integrations use their own API pages, not the Customer Card, so a rule on the card page doesn't reach them either. If your data quality problem arrived through an integration, page properties were never going to catch it.

Configuration packages and RapidStart. Validation is optional per field during a package import. Microsoft's instruction for configuration packages reads: "To specify that the field data shouldn't be validated, clear the Validate Field check box for the field." Clearing it is a quick way to get a stubborn import through, and then the largest batch of master data you'll ever load lands unvalidated.

This path deserves its own test, whichever technique you picked. Import a package into a sandbox with Validate Field cleared and see whether your rule fires. If it doesn't, add a data quality check that runs after the import and before the company goes live.

Number, Option and Enum fields. These always hold a value. TestField treats 0 as missing, which catches an empty quantity but also rejects a legitimate zero. An Option or Enum field always sits on one of its values. For these fields the useful rule states which values are acceptable, such as Unit Cost >0, rather than checking whether something is filled in.

The gap between entry and posting. If your only guard sits in the posting routine, the incomplete record already exists. It's already in your item list, your reports, your Power BI dataset and whatever integration reads the table. The posting error tells one user, late, about a problem that has been spreading for weeks.

Choosing between them

  • You want a hint on one page so users know what's expected: ShowMandatory.
  • You want to stop someone clearing a key value they already entered: NotBlank.
  • You own the extension and need a hard block on a specific process: TestField in the relevant trigger or codeunit.
  • Your rules differ per company, per role or per situation, and you want to maintain them without a release: configurable rules.

A common setup combines the first with one of the last two: the asterisk tells users what's expected, and the rule makes sure it happens.

A five-step test to prove your rule holds

Run this against any field you believe is mandatory. Each step covers a different way data gets in.

  1. Create the record, leave the field empty, close the page. Does the record exist?
  2. Fill the field, clear it again, tab out. Do you get an error?
  3. Create the record through Edit in Excel or an API call with the field omitted.
  4. Import a configuration package that includes the table with Validate Field cleared for that field.
  5. Post or release a document that uses the record.

Every step that lets an empty value through is an open path. Steps 3 and 4 bypass the card page, so they are the ones to watch.

Habits that keep mandatory fields meaningful

Give every mandatory field a named owner and a written reason. Fields nobody can justify get filled with "x" and "n/a", which is worse than an empty field because it looks complete in a report.

Enforce at the earliest point where the data is actually knowable. Requiring a delivery address on a lead that has just been created teaches people to work around the rule.

Write error messages that name the record and say what to do. "Field must have a value" costs a support ticket. "Payment Terms Code is required before customer 10000 can be unblocked" doesn't.

Retest your rules after every Business Central update, especially anything that relies on standard events or page properties.

Check your historical data before switching a rule on. A new rule doesn't reach back into existing records by itself, so the first person to touch an old record inherits a problem they didn't create. Clean the backlog first (the Field Validation app has a Check Table action for this), or scope the rule so it only applies to new records for the first period.

Frequently asked questions