Generic Validator Method Pattern

Generic Validator Method Pattern is a design pattern which is an extension of Generic Method Pattern. Purpose of this design pattern is to validate one or more entities in a specific context. This is a very commonly used pattern in other languages, just that it is adjusted to Generic Method Pattern.


Generic Method Pattern

It has a public method and two business events which can be subscribed to change or extend the behaviour of the method.


Public Method may contain the following sequence of calls:

  1. UI Confirmation (Optional)

  2. OnBefore Business Event

  3. Execute Logic

  4. OnAfter Business Event

  5. UI Acknowledgement (Optional)

Generic Method Pattern better explained in "Design patterns for developing repeatable IP for Dynamics 365 Business Central"


Generic Validator Method Pattern

It has two public methods and two business events which can be subscribed to change or extend the behaviour of the method.


This pattern contains HasErrors and Validate public functions.


HasErrors Method

This method will check validation errors in the entity and stores errors in Errors parameter and returns true if there are any validation errors.


This method should contain the following sequence of calls:

  1. OnBefore Business Event

  2. Execute Logic

  3. OnAfter Business Event

Validate Method

This method will throw a multi line error message with all validation errors found in HasErrors method.


Sample Code

codeunit 50101 CreateSalesOrderValidator
{
    procedure Validate(Customer: Record Customer)
    var
        Errors: List of [Text];
    begin
        if HasErrors(Customer, Errors) then
            Error(ErrorsToText(Errors));
    end;

    procedure HasErrors(Customer: Record Customer; Errors: List of [Text]): Boolean
    var
        Handled: Boolean;
    begin
        OnBeforeCreateSalesOrderValidator(Customer, Handled);
        DoCreateSalesOrder(Customer, Errors, Handled);
        OnAfterCreateSalesOrderValidator(Customer);

        if Errors.Count() > 0 then
            exit(true);
    end;

    local procedure ErrorsToText(Errors: List of [Text]): Text
    var
        ErrText: Text;
        TxtBuffer: TextBuilder;
    begin
        foreach ErrText in Errors do
            TxtBuffer.AppendLine(ErrText);

        exit(TxtBuffer.ToText());
    end;

    local procedure DoCreateSalesOrder(Customer: Record Customer; Errors: List of [Text]; Handled: Boolean)
    begin
        if Handled then
            exit;

        ValidateGenBusinessPostingGroup(Customer, Errors);
        ValidateVATBusPostingGroup(Customer, Errors);
        ValidateVATRegistrationNo(Customer, Errors);
    end;

    local procedure ValidateGenBusinessPostingGroup(Customer: Record Customer; Errors: List of [Text])
    var
        GenBusPostingGroupErr: Label 'Gen. Bus. Posting Group should not be empty.';
    begin
        if Customer."Gen. Bus. Posting Group" = '' then
            Errors.Add(GenBusPostingGroupErr);
    end;

    local procedure ValidateVATBusPostingGroup(Customer: Record Customer; Errors: List of [Text])
    var
        GenBusPostingGroupErr: Label 'VAT Bus. Posting Group should not be empty.';
    begin
        if Customer."VAT Bus. Posting Group" = '' then
            Errors.Add(GenBusPostingGroupErr);
    end;

    local procedure ValidateVATRegistrationNo(Customer: Record Customer; Errors: List of [Text])
    var
        GenBusPostingGroupErr: Label 'Customer should have a valid VAT Registration No.';
    begin
        if Customer."VAT Registration No." = '' then
            Errors.Add(GenBusPostingGroupErr);
    end;

    [BusinessEvent(false)]
    local procedure OnBeforeCreateSalesOrderValidator(Customer: Record Customer; var Handled: Boolean)
    begin
    end;

    [BusinessEvent(false)]
    local procedure OnAfterCreateSalesOrderValidator(Customer: Record Customer)
    begin
    end;
}

Use Cases

This pattern can be used in the following senarios:

  • Postings, Actions

Validate Transactional Entities before posting or before performaning an action.

  • APIs, Web Services

Validating Entities before importing or accepting data via APIs or Web Services.


#MSDyn365 #MSDyn365BC #BusinessCentral #DynamicsNAV #DesignPatterns