Skip to main content
All docs
V25.1
  • Audit Trail Module (XPO)

    • 5 minutes to read

    The Audit Trail is implemented by the DevExpress.ExpressApp.AuditTrail.Xpo.v25.1.dll assembly. Use approaches described in the following topic to add the module to your application: Register a Built-in XAF Module.

    Check that the DevExpress.Persistent.Base.v25.1.dll assembly is referenced in your application, since it contains XAF-independent services used by the Audit Trail module.

    Audited Objects

    The Audit Trail Module logs changes in the following objects and properties:

    • Persistent classes inherited from the Base Persistent Classes.
    • Public writable simple and reference properties defined in persistent classes.
    • Public collection properties defined in persistent classes.

    Technical Notes and Details

    • The module also saves the current user name provided by the Security System.
    • Real values of properties stored as blob data (for instance, images) are not saved. The “Blob data” string is saved instead.
    • Null values are saved as the “N/A” string.

    When the object is modified in the Detail View, the initial values are copied immediately when an object has been loaded. When the object is modified in Editable List View, initial values are copied in the BaseObjectSpace.ObjectChanged event. The actual values are collected and saved in a separate UnitOfWork in the BaseObjectSpace.Committed event.

    In code, changes are represented by the AuditDataItem class. This class’ properties are logged. By default, they are saved to the database by an AuditDataStore object. This object creates an AuditDataItemPersistent persistent object and saves it to the database. To save changes represented by the AuditDataItem objects in another storage, inherit a custom class from the AuditDataStore class and override the Save method (see the Customize the Audit Trail System topic).

    Audit Trail Module Databases

    Audit information is logged to the application database. The Audit Trail module adds the following tables to the database:

    AuditDataItemPersistent

    The table where AuditDataItemPersistent objects are stored. Each time one of the changes listed above is made, a new record is added to this table. The table’s AuditedObject field contains references to the corresponding records in the AuditObjectWeakReference table. The OldObject and NewObject fields contain references to the corresponding records in the XPWeekReference table. String representations of these fields are stored in the OldValue and NewValue fields, respectively.

    Note

    • The AuditedObject is null for deleting operation when the deferred deletion option is disabled for the audited type. Use the DeferredDeletionAttribute to enable it.
    • For collection modification entries (AddedToCollection, RemovedFromCollection, CollectionObjectChanged, AggregatedObjectChanged), a reference to the modified persistent object along with the object’s string representation are always stored into the OldObject / OldValue fields.
    • The Security System creates a default user that cannot access or change the audit data records. To allow a user to access these records, use the following permissions:

      // MySolution.Module/DatabaseUpdater/Updater
      defaultRole.AddTypePermission<AuditDataItemPersistent>(SecurityOperations.Read, SecurityPermissionState.Deny);
      defaultRole.AddObjectPermissionFromLambda<AuditDataItemPersistent>(SecurityOperations.Read, a => a.UserObject.Key == CurrentUserIdOperator.CurrentUserId().ToString(), SecurityPermissionState.Allow);
      defaultRole.AddTypePermission<AuditEFCoreWeakReference>(SecurityOperations.Read, SecurityPermissionState.Allow);
      
    XPWeakReference
    Contains data on the objects that have been changed. Object identifiers are stored as strings.
    AuditedObjectWeakReference
    Contains data on both objects that have been changed and objects that have taken part in a change. Object identifiers are stored in the GuidId or IntId field, depending on whether they are stored as Guid or integer values. Thus, the AuditedObjectWeakReference table represents a more convenient way to access object data in comparison to the XPWeakReference table.

    Work with a Session

    It is possible to lose some of the object changes if these changes are performed within a session that is not audited. This can occur if you manually create a Session or UnitOfWork. To avoid such a failure, use the CreateObjectSpace method when you need to create your own Session or UnitOfWork:

    IObjectSpace objectSpace = Application.CreateObjectSpace(typeof(MyBusinessClass));
    // do not write a statement like the following
    // Session session = new Session(...);
    

    Customize Change Logging in Non-Persistent Properties

    The following property controls change logging for all non-persistent properties: DevExpress.Persistent.AuditTrail.ObjectAuditProcessor.ExcludeNonPersistentFromAudit. This property is set to true if the FrameworkSettingsCompatibilityMode property is v24_1 or higher. To enable change logging for individual non-persistent properties, apply a UseInAuditTrailAttribute and set its parameter to true.

    If you want to enable change tracking for non-persistent properties globally, set the DevExpress.Persistent.AuditTrail.ObjectAuditProcessor.ExcludeNonPersistentFromAudit property to false. To disable change logging for individual non-persistent properties, apply a UseInAuditTrailAttribute and set its parameter to false.

    Middle Tier Security Specifics

    Important

    In .NET Framework applications with WCF-based Middle Tier security (XPO), the client application requires rights to write to the AuditDataItemPersistent database table for the Audit Trail Module to work correctly. This may pose a security risk because it allows users to edit records in this table. Do not use our Audit Trail Module in this configuration unless you implement additional data protection on your database server or application side manually. We recommend that you migrate your application to .NET and use an ASP.NET Core WebAPI-based Middle Tier Security server. In this configuration, the audit is performed entirely on the server.

    In .NET applications, you need to add the Audit Trail Module only to the server application:

    public class Startup {
        // ...
        public void ConfigureServices(IServiceCollection services) {
            // ...
            services.AddXafMiddleTier(Configuration, builder => {
                builder.Modules
                    .AddAuditTrailXpo()
                    // ...
            }
        }
    }
    
    See Also