Open Source Web Application Framework for ASP.NET Core
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

5.1 KiB

//[doc-seo]
{
    "Description": "Add custom business logic to dynamic entity CRUD operations using Interceptors in the ABP Low-Code Module. Validate, transform, and react to data changes with JavaScript."
}

Interceptors

Interceptors allow you to run custom JavaScript code before or after Create, Update, and Delete operations on dynamic entities.

Interceptor Types

Command Type When Executed
Create Pre Before entity creation — validation, default values
Create Post After entity creation — notifications, related data
Update Pre Before entity update — validation, authorization
Update Post After entity update — sync, notifications
Delete Pre Before entity deletion — dependency checks
Delete Post After entity deletion — cleanup

Defining Interceptors with Attributes

Use the [DynamicEntityCommandInterceptor] attribute on a C# class:

[DynamicEntity]
[DynamicEntityCommandInterceptor(
    "Create",
    InterceptorType.Pre,
    "if(!context.commandArgs.data['Name']) { globalError = 'Name is required!'; }"
)]
[DynamicEntityCommandInterceptor(
    "Create",
    InterceptorType.Post,
    "context.log('Entity created: ' + context.commandArgs.entityId);"
)]
public class Organization
{
    public string Name { get; set; }
}

The Name parameter must be one of: "Create", "Update", or "Delete". This maps directly to the CRUD command being intercepted. Multiple interceptors can be added to the same class (AllowMultiple = true).

Defining Interceptors in model.json

Add interceptors to the interceptors array of an entity:

{
  "name": "LowCodeDemo.Customers.Customer",
  "interceptors": [
    {
      "commandName": "Create",
      "type": "Pre",
      "javascript": "if(context.commandArgs.data['Name'] == 'Invalid') {\n  globalError = 'Invalid Customer Name!';\n}"
    }
  ]
}

Interceptor Descriptor

Field Type Description
commandName string "Create", "Update", or "Delete"
type string "Pre" or "Post"
javascript string JavaScript code to execute

JavaScript Context

Inside interceptor scripts, you have access to:

context.commandArgs

Property Type Description
data object Entity data dictionary (for Create/Update)
entityId string Entity ID (for Update/Delete)
getValue(name) function Get a property value
setValue(name, value) function Set a property value (Pre-interceptors only)

context.currentUser

Property Type Description
isAuthenticated bool Whether user is logged in
userName string Username
email string Email address
roles string[] User's role names
id string User ID

context.emailSender

Method Description
sendAsync(to, subject, body) Send an email

context.log(message)

Log a message (use instead of console.log).

db (Database API)

Full access to the Scripting API for querying and mutating data.

globalError

Set this variable to a string to abort the operation and return an error:

globalError = 'Cannot delete this entity!';

Examples

Pre-Create: Validation

{
  "commandName": "Create",
  "type": "Pre",
  "javascript": "if(!context.commandArgs.data['Name']) {\n  globalError = 'Organization name is required!';\n}"
}

Post-Create: Email Notification

{
  "commandName": "Create",
  "type": "Post",
  "javascript": "if(context.currentUser.isAuthenticated && context.emailSender) {\n  await context.emailSender.sendAsync(\n    context.currentUser.email,\n    'New Order Created',\n    'Order total: $' + context.commandArgs.data['TotalAmount']\n  );\n}"
}

Pre-Update: Role-Based Authorization

{
  "commandName": "Update",
  "type": "Pre",
  "javascript": "if(context.commandArgs.data['IsDelivered']) {\n  if(!context.currentUser.roles.includes('admin')) {\n    globalError = 'Only administrators can mark orders as delivered!';\n  }\n}"
}

Pre-Delete: Business Rule Check

{
  "commandName": "Delete",
  "type": "Pre",
  "javascript": "var project = await db.get('LowCodeDemo.Projects.Project', context.commandArgs.entityId);\nif(project.Budget > 100000) {\n  globalError = 'Cannot delete high-budget projects!';\n}"
}

Pre-Update: Negative Value Check

{
  "commandName": "Update",
  "type": "Pre",
  "javascript": "if(context.commandArgs.data['Quantity'] < 0) {\n  globalError = 'Quantity cannot be negative!';\n}"
}

Pre-Create: Self-Reference Check

{
  "commandName": "Update",
  "type": "Pre",
  "javascript": "if(context.commandArgs.data.ParentCategoryId === context.commandArgs.entityId) {\n  globalError = 'A category cannot be its own parent!';\n}"
}

See Also