Repository navigation
platform sdk custom fields
In Security Center, custom fields are user-defined attributes attached to entities. They let an integration store domain-specific data on cardholders, areas, doors, or any other entity type without modifying the schema. The Platform SDK manages them through the ICustomFieldService exposed on the system configuration entity:
SystemConfiguration systemConfig = engine.GetEntity<SystemConfiguration>(
SystemConfiguration.SystemConfigurationGuid);
ICustomFieldService service = systemConfig.CustomFieldService;Common use cases:
- Define new custom field types for cardholders, doors, or other entities (text, numeric, boolean, date, decimal, image, entity reference).
- Attach domain-specific data to existing entities, such as a department on a cardholder or a contractor agency on a credential.
- Read or update custom field values across many entities in bulk through the service.
- Read or write a single entity's custom fields directly through
Entity.GetCustomFields()andEntity.SetCustomField().
The same read and write operations are available through the service (passing the target entity's Guid) or through any Entity instance's GetCustomFields() and SetCustomField() methods. The entity-side methods delegate to the service with the entity's own Guid, so the two paths are interchangeable.
Each custom field is described by a CustomField object. Enumerate every defined field through service.CustomFields, or fetch one by identifier, by name and entity type, or by name and owner:
IReadOnlyList<CustomField> all = service.CustomFields;
CustomField byId = service.GetCustomField(customFieldGuid);
CustomField byName = service.GetCustomField(
"Department", EntityType.Cardholder);
CustomField byOwner = service.GetCustomField(
"Department", EntityType.Cardholder, ownerGuid);CustomField carries the field's Guid, Name, EntityType, ValueType, Mandatory, Unique, IsEncrypted, DefaultValue, GroupName, GroupPriority, and Owner. The display-related properties (Name, GroupName, GroupPriority, IsEncrypted, ShowInReports, DefaultValue) are writable; identity and typing properties are read-only after the field is built.
The CustomFieldValueType enum selects the value shape used by a custom field:
| Member | Value | Use for |
|---|---|---|
Text |
0 | String values. |
Numeric |
1 | Integer values. |
Boolean |
2 | True or false. |
DateTime |
3 | Date and time values. |
Decimal |
4 | Decimal values. |
Image |
5 | Image values; the boxed value must be a System.Drawing.Image. |
Entity |
6 | A reference to another entity, stored as a Guid. |
Date |
7 | Date-only values. |
Use service.CreateCustomFieldBuilder() and the fluent setters, then call Build() to produce a CustomField. Persist the new definition with AddCustomFieldAsync(...) (or the synchronous AddCustomFields(...)):
CustomField field = service.CreateCustomFieldBuilder()
.SetName("Department")
.SetEntityType(EntityType.Cardholder)
.SetValueType(CustomFieldValueType.Text)
.SetDefaultValue("Unassigned")
.Build();
await service.AddCustomFieldAsync(field);Build() enforces these rules:
-
SetName,SetEntityType, andSetValueTypeare required.Build()throwsInvalidOperationExceptionif any of the three is missing. -
Namemust be unique by the combination ofEntityType,Owner, andCustomEntityTypeId. A duplicate raisesInvalidOperationException. - A unique custom field must also be mandatory. Calling
SetUnique(true)withoutSetMandatory(true)raisesInvalidOperationException. -
Mandatoryis not supported onAccessControlUnit,VideoUnit,LprUnit, orIntrusionUnitentity types.SetMandatory(true)on one of these (orBuild()after such an attempt) raises an exception. - When
EntityTypeisEntityType.CustomEntity,SetCustomEntityTypeIdis required and must be a non-emptyGuid. For every other entity type,SetCustomEntityTypeIdmust not be set. -
GroupPrioritymust be greater than zero. - For
DateTimevalue types, the default value must be aDateTimeinstance or a parseable date string.Local-kind values are converted to UTC; unspecified-kind values are treated as UTC.
AddCustomFieldAsync(field) and AddCustomFields(field) both raise SdkException(SdkError.AlreadyExist) if a field with the same Name/EntityType/Owner/CustomEntityTypeId combination already exists, and SdkException(SdkError.InvalidEntityType) if the entity type is not supported for custom fields.
To reuse a previously defined CustomFieldType (a constrained list of allowed values), pass it to the SetValueType(CustomFieldType) overload instead of the value-type enum.
Read through the service or through the entity. Both return the boxed value, with generic <T> overloads for typed access:
object department = service.GetValue(field, cardholder.Guid);
string typed = service.GetValue<string>(field, cardholder.Guid);
string byName = service.GetValue<string>(
"Department", cardholder.Guid);
IReadOnlyList<CustomFieldValue> values =
await cardholder.GetCustomFieldsAsync();
CustomFieldValue companyValue = values.FirstOrDefault(
v => v.Name == "Company");GetCustomFields() and GetCustomFieldsAsync() return IReadOnlyList<CustomFieldValue>. Each CustomFieldValue exposes CustomField, Name, ValueType, and Value.
Write through the service (synchronous or asynchronous) or through the entity:
service.SetValue(field, cardholder.Guid, "Engineering");
await service.SetValueAsync(field, cardholder.Guid, "Engineering");
cardholder.SetCustomField(field, "Engineering");
await cardholder.SetCustomFieldAsync("Department", "Engineering");SetValue and SetValueAsync compare the new value against the current value and skip the write when they match. Image-typed fields require the value to be a System.Drawing.Image instance.
To reset a field to its configured default, call ClearValue:
service.ClearValue(field, cardholder.Guid);ClearValue writes the field's DefaultValue, not null. It raises SdkException(SdkError.InvalidValue) if the field has no default value defined.
Remove a definition by its identifier:
service.RemoveCustomField(field.Guid);
await service.RemoveCustomFieldAsync(field.Guid);Both overloads validate access and ownership and raise KeyNotFoundException if no matching definition is found.
For the Web SDK equivalent, see Web SDK custom fields.
- Overview
- Connecting to Security Center
- SDK certificates
- Referencing SDK assemblies
- ASP.NET hosting
- SDK compatibility
- Migrating to modern .NET
- Entities
- Entity cache
- Entity loading, cache, and query options
- Detecting entity changes
- Entity change event reference
- Transactions
- Security Center events
- Actions
- Security Desk
- Custom events
- Event-to-actions
- Managing macros
- ReportManager
- ReportManager query reference
- Access control raw events
- DownloadAllRelatedData and StrictResults
- Privileges
- Partitions
- Entity write restrictions
- About custom fields
- About video
- About cameras
- Enrolling a video unit
- Ingesting third-party video
- Archiver and auxiliary archiver roles
- Archive transfer
- About access control
- About cardholders and credentials
- About doors, areas, elevators, and access points
- About access rules and schedules
- About access control units and interface modules
- Enrolling an access control unit
- Door templates
- Visitors
- Mobile credentials
- About threat levels
- About alarms
- About incidents
- Maps
- Logging
- Overview
- Localization
- Certificates
- Lifecycle
- Threading
- State management
- Configuration
- Restricted configuration
- Events
- Queries
- Request manager
- Database
- Entity ownership
- Engine extensions
- Entity mappings
- Server management
- Custom privileges
- Custom entity types
- Resolving non-SDK assemblies
- Deploying plugins
- Modern .NET support
- Overview
- Localization
- Certificates
- Creating modules
- Tasks
- Pages
- Components
- Tile extensions
- Services
- Contextual actions
- Custom actions
- Options extensions
- Configuration pages
- Monitors
- Shared components
- Commands
- Extending events
- Map extensions
- Timeline providers
- Image extractors
- Credential encoders
- Credential readers
- Cardholder fields extractors
- Badge printers
- Content builders
- Dashboard widgets
- Incidents
- Logon providers
- Pinnable content builders
- Custom report pages
- Overview
- Getting started
- Media file formats
- MediaPlayer
- VideoSourceFilter
- MediaExporter
- MediaFile
- G64 converters
- FileCryptingManager
- PlaybackSequenceQuerier
- PlaybackStreamReader
- OverlayFactory
- PtzCoordinatesManager
- AudioTransmitter
- AudioRecorder
- AnalogMonitorController
- Camera blocking
- Overview
- Getting started
- Referencing entities
- Entity operations
- About access control in the Web SDK
- About video in the Web SDK
- Users and user groups
- Partitions
- Custom fields
- Custom card formats
- Actions
- Events and alarms
- Incidents
- Reports
- Tasks
- Macros
- Custom entity types
- System endpoints
- Performance guide
- Reference
- Endpoints
- Constants
- Enumerations
- Under the hood
- Troubleshooting