mirror of https://github.com/abpframework/abp.git
csharpabpc-sharpframeworkblazoraspnet-coredotnet-coreaspnetcorearchitecturesaasdomain-driven-designangularmulti-tenancy
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
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}"
}