ZuloOne
English
Sign in
Menu

Dictionary — dictionary

Updated

What it is#

Master data: an entity with an independent life cycle (it is created, edited, and referenced by documents and registers). It may be hierarchical (isHierarchical; then the server creates the ParentId field itself). It may be isSingleton — exactly one record per tenant, usually for "module settings" (InventorySettings, CommonSettings, and so on).

JSON envelope#

Pair of files: <Name>.object.json (design) + Events/<Name>EventHandler.script.json + Events/<Name>EventHandler.cs (event code).

<Name>.object.json, "kind": "Dictionary":

{
  "kind": "Dictionary",
  "object": {
    "caption": { "en": "Countries", "ru": "Страны", "uk": "Країни" },
    "isHierarchical": false,
    "isSingleton": false,
    "isVersioned": false,
    "isCached": false,
    "numberSequenceMetaId": "<GUID NumberSequence>",
    "defaultSearchProperty": "Name",
    "displayFormat": "{Name} - ({CodeISO2})",
    "metaId": "<GUID Dictionary>",
    "name": "Country",
    "modelId": "<GUID Model>"
  },
  "fields": [
    {
      "dictionaryMetaId": "<GUID Dictionary>",
      "fieldName": "CodeISO2",
      "baseType": "String", "length": 2,
      "isRequired": false, "displayOrder": 2, "isVisible": true,
      "caption": { "en": "ISO2 code", "ru": "Код ISO2" },
      "metaId": "<GUID Field>", "name": "CodeISO2", "modelId": "<GUID Model>"
    },
    {
      "dictionaryMetaId": "<GUID Dictionary>",
      "fieldName": "Currency",
      "edtMetaId": "<GUID EDT Reference>",
      "isRequired": false, "displayOrder": 5, "isVisible": true,
      "caption": { "en": "Currency", "ru": "Валюта" },
      "metaId": "<GUID Field>", "name": "Currency", "modelId": "<GUID Model>"
    }
  ]
}

A field is either scalar (baseType + length/precision/scale) or a reference (edtMetaId to a Reference EDT — see EDT); there is no third option (EDT-first, see the root CLAUDE.md). The server creates ID itself on import (and a number sequence for it if you do not declare your own). You do not need to write this field; it appears in the file after the first export from the database.

C# base#

<Name>EventHandler : TypedDictionaryEventHandler<Name> — the base is declared manually (the first chain link, does not call next). A typed record (record.SomeField) arrives in every hook.

Events / Chain of Command#

The full set of life-cycle hooks: OnBeforeCreateAsync, OnBeforeSaveAsync/OnAfterSaveAsync (any save), operational OnBefore/AfterInsert/UpdateAsync (an override is used instead of the Before/AfterSave call for this operation), OnBeforeDeleteAsync/OnAfterDeleteAsync, OnBeforeCloneAsync, OnAfterLoadAsync, OnValidateFieldAsync, OnSaveFailedAsync/OnDeleteFailedAsync (replacing a raw database error with friendly text). Extension from another model uses [ExtensionOf("Country")] on the class + next(...) in every override, with the suffix Ext<Model>EventHandler.

Example#

Country in Common — no hierarchy, reference to Currency; a settings singleton dictionary is InventorySettings in Inventory.

Was this page helpful?