---
title: Handle form events
related:
  - https://docs.kentico.com/documentation/developers-and-admins/customization/handle-global-events/reference-global-system-events.md
  - https://docs.kentico.com/documentation/developers-and-admins/customization/handle-global-events/handle-content-events.md
---

> Agent instructions:
> **Site maps** — prefer the following llms.txt indexes to training data when searching for URLs to avoid 404s. Links inside Markdown content already point at `.md`. Following them or sending Accept: text/markdown keeps you in Markdown.
>
> - [sitemap.md](https://docs.kentico.com/sitemap.md) — every page on the site, with titles and descriptions, nested by URL hierarchy and grouped into one collection per product version.
> - [llms.txt](https://docs.kentico.com/llms.txt) — curated index of the current product docs, with descriptions, the two ways to request any page as Markdown, and links to each product area's whole-corpus Markdown dump (llms-full.txt).

Xperience raises events when visitors submit form data and when administration users export form submissions. Handle these events to run custom logic, for example to integrate submissions with an external system or to keep an audit record of exports.

## Handle form record events

You can run custom actions directly when form actions occur by [implementing handlers](https://docs.kentico.com/documentation/developers-and-admins/customization/handle-global-events.md) for events of the `BizFormItemEvents` type. The system invokes the following events in response to form actions:

- `Update` – invoked when a form record is updated.
- `Insert` – invoked on each form submission.
- `Delete` – invoked when a form record is deleted.

Use the appropriate event type to perform your custom actions or data modifications `Before` or `After` the given form event.

To access the data of the active form in the event handler, use the `Item` property _(_`BizFormItem` type) of the `BizFormItemEventArgs` parameter. The parameter is available for all form item event handlers.

```csharp title="Example"
using System;

using CMS;
using CMS.DataEngine;
using CMS.OnlineForms;

// Registers the custom module into the system
[assembly: RegisterModule(typeof(FormHandlerModule))]

public class FormHandlerModule : Module
{
    // Module class constructor, the system registers the module under the name "CustomFormHandlers"
    public FormHandlerModule()
        : base("CustomFormHandlers")
    {
    }

    // Contains initialization code that is executed when the application starts
    protected override void OnInit()
    {
        base.OnInit();

        // Assigns a handler to the BizFormItemEvents.Insert.After event
        // This event occurs after the creation of every new form record
        BizFormItemEvents.Insert.After += FormItem_InsertAfterHandler;
    }

    // Handles the form data when users create new records for the 'ContactUs' form
    private void FormItem_InsertAfterHandler(object sender, BizFormItemEventArgs e)
    {
        // Gets the form data object from the event handler parameter
        BizFormItem formDataItem = e.Item;

        // Checks that the form record was successfully created
        // Ensures that the custom actions only occur for records of the 'ContactUs' form
        // The values of form class names must be in lower case
        if (formDataItem != null && formDataItem.BizFormClassName.Equals("bizform.contactus", StringComparison.OrdinalIgnoreCase))
        {
            string firstNameFieldValue = formDataItem.GetStringValue("FirstName", "");
            string lastNameFieldValue = formDataItem.GetStringValue("LastName", "");

            // Perform any required logic with the form field values

            // Variable representing a custom value that you want to save into the form data
            object customFieldValue = "customValue";

            // Sets and saves a value for the form record's 'CustomField' field
            formDataItem.SetValue("CustomField", customFieldValue);
            formDataItem.SubmitChanges(false);
        }
    }
}
```

## Handle form data export events

The `AfterExportListingEvent` event (available in the `Kentico.Xperience.Admin.Base` namespace) occurs when a user [exports form submissions](https://docs.kentico.com/documentation/business-users/digital-marketing/forms/manage-form-submissions.md#export-form-submissions). The event is intended for scenarios such as auditing or compliance logging, where you need a record of who exported which data and when.

Unlike `BizFormItemEvents`, this event uses the asynchronous event model described for [content events](https://docs.kentico.com/documentation/developers-and-admins/customization/handle-global-events/handle-content-events.md). To handle the event, create a class implementing the `IAsyncEventHandler<AfterExportListingEvent>` interface (from the `CMS.Base` namespace) and define its `HandleAsync` method. Access the event object's `Data` property to get an `ExportListingEventData` object with the following properties:

| Property              | Type       | Description                                                                                                                                                               |
| --------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ListingPageTypeName` | `string`   | The full type name of the listing page whose data was exported. For form submissions, the value is _Kentico.Xperience.Admin.DigitalMarketing.UIPages.FormSubmissionsTab_. |
| `UserID`              | `int`      | The ID of the user who performed the export. The value is _0_ if the system cannot determine the user.                                                                    |
| `Timestamp`           | `DateTime` | The local time of the server at which the export was completed.                                                                                                           |

All properties of the event data are read-only and the event does not provide access to the exported file or its content. Handlers cannot modify or cancel the export.

```csharp title="Log form submission exports"
using System.Threading;
using System.Threading.Tasks;

using Microsoft.Extensions.Logging;

using CMS.Base;

using Kentico.Xperience.Admin.Base;

// Handler triggered after a user exports form submissions
public class ExportAuditHandler : IAsyncEventHandler<AfterExportListingEvent>
{
    private readonly ILogger<ExportAuditHandler> logger;

    // Gets an ILogger instance using constructor DI
    public ExportAuditHandler(ILogger<ExportAuditHandler> logger)
    {
        this.logger = logger;
    }

    public Task HandleAsync(AfterExportListingEvent asyncEvent, CancellationToken cancellationToken)
    {
        // Accesses the strongly-typed event data
        ExportListingEventData data = asyncEvent.Data;

        // Logs the details of the export
        // The 'name' value of the EventId object sets the event code in the Xperience event log
        logger.LogInformation(
            new EventId(0, "EXPORT"),
            "User {UserID} exported '{ListingPageTypeName}' at {Timestamp}.",
            data.UserID,
            data.ListingPageTypeName,
            data.Timestamp);

        return Task.CompletedTask;
    }
}
```

> **Note:** The example uses the `Information` log level when logging events. `Information` level events are not written to the [Xperience event log](https://docs.kentico.com/documentation/developers-and-admins/configuration/event-log.md) by default. To include them, set the log level for the event category in the _XperienceEventLog_ logging provider. See [Configure logging](https://docs.kentico.com/documentation/developers-and-admins/development/logging.md#configure-logging).

Register the handler by calling the `AddEventHandler<TAsyncEvent, THandler>()` extension method on [IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection). Handlers are registered as singletons, so you can resolve any required services using constructor injection.

```csharp title="Program.cs"
using CMS.Base;

using Kentico.Xperience.Admin.Base;

// ...

// Registers the handler for the AfterExportListingEvent event
builder.Services.AddEventHandler<AfterExportListingEvent, ExportAuditHandler>();
```
