Skip to main content
All docs
V24.2

DevExpress v24.2 Update — Your Feedback Matters

Our What's New in v24.2 webpage includes product-specific surveys. Your response to our survey questions will help us measure product satisfaction for features released in this major update and help us refine our plans for our next major release.

Take the survey Not interested

Audit the Current User or Host Identity (EF Core)

  • 3 minutes to read

The Audit Trail Module gets information on the user who changed an object from the Security System. If your application uses custom authentication instead of the Security System, you can use the following properties to determine the user:

#ASP.NET Core Blazor

  1. In the ASP.NET Core Blazor application project (MySolution.Blazor.Server), create the following new classes:

    • MyUserProvider that implements the IAuditUserProvider interface
    • MyAuditDefaultStringProvider that is an AuditDefaultStringProvider descendant
    using DevExpress.ExpressApp.Security;
    using DevExpress.ExpressApp.Services.Localization;
    using DevExpress.Persistent.BaseImpl.EFCore.AuditTrail;
    
    public class MyUserProvider : IAuditUserProvider {
        private readonly IPrincipalProvider principalProvider;
        public MyUserProvider(IPrincipalProvider principalProvider) {
            this.principalProvider = principalProvider;
        }
        public object GetUser() {
            return principalProvider.User.Identity.Name;
        }
        public object GetUserId() {
            return principalProvider.User.Identity.Name;
        }
        public Type GetUserType() {
            return typeof(string);
        }
    }
    
    public class MyAuditDefaultStringProvider : AuditDefaultStringProvider {
        public MyAuditDefaultStringProvider(ICaptionHelperProvider captionHelperProvider)
            : base(captionHelperProvider) { }
        public override string GetDefaultString(object targetObject, Type objectType, object objectKey) {
            if(targetObject.GetType().Equals(typeof(string))) {
                return targetObject.ToString();
            }
            return base.GetDefaultString(targetObject, objectType, objectKey);
        }
    }
    
  2. In the Startup.ConfigureServices method (the MySolution.Blazor.Server\Startup.cs file), do the following:

    • add the custom implementation of the IPrincipalProvider service (HttpContextPrincipalProvider);
    • set the AuditUserProviderType and AuditDefaultStringProviderType properties to the custom MyUserProvider and MyAuditDefaultStringProvider types.

    File: MySolution.Blazor.Server\Startup.cs

    using DevExpress.Persistent.BaseImpl.EFCore.AuditTrail;
    
    public class Startup {
        // ...
        public void ConfigureServices(IServiceCollection services) {
            // ...
            services.AddScoped(typeof(IPrincipalProvider), typeof(HttpContextPrincipalProvider));
            services.AddXaf(Configuration, builder => {
                // ...
                builder.ObjectSpaceProviders
                    .AddEFCore(options => options.PreFetchReferenceProperties())
                        .WithAuditedDbContext(contexts => {
                            contexts.Configure<MySolutionEFCoreDbContext, MySolutionAuditingDbContext>(
                                (serviceProvider, businessObjectDbContextOptions) => {
                                    // ...
                                },
                                (serviceProvider, auditHistoryDbContextOptions) => {
                                    // ...
                                },
                                auditTrailOptions => {
                                    auditTrailOptions.AuditUserProviderType = typeof(MyUserProvider);
                                    auditTrailOptions.AuditDefaultStringProviderType = typeof(MyAuditDefaultStringProvider);
                                });
                        })
                    // ...
    

Note

The MyUserProvider and MyAuditDefaultStringProvider types are registered as scoped services. You can use the IAuditUserProvider and IAuditDefaultStringProvider interfaces to access them.

#WinForms

  1. In the WinForms application project (MySolution.Win), create the following new classes:

    • MyUserProvider that implements the IAuditUserProvider interface
    • MyAuditDefaultStringProvider that is an AuditDefaultStringProvider descendant
    using DevExpress.ExpressApp.Services.Localization;
    using DevExpress.Persistent.BaseImpl.EFCore.AuditTrail;
    using System.Security.Principal;
    
    public class MyUserProvider : IAuditUserProvider {
        public object GetUser() {
            return WindowsIdentity.GetCurrent().Name;
        }
        public object GetUserId() {
            return WindowsIdentity.GetCurrent().Name;
        }
        public Type GetUserType() {
            return typeof(string);
        }
    }
    
    public class MyAuditDefaultStringProvider : AuditDefaultStringProvider {
        public MyAuditDefaultStringProvider(ICaptionHelperProvider captionHelperProvider)
            : base(captionHelperProvider) { }
        public override string GetDefaultString(object targetObject, Type objectType, object objectKey) {
            if(targetObject.GetType().Equals(typeof(string))) {
                return targetObject.ToString();
            }
            return base.GetDefaultString(targetObject, objectType, objectKey);
        }
    }
    
  2. In the ApplicationBuilder.BuildApplication method (MySolution.Win\Startup.cs file), set the AuditUserProviderType and AuditDefaultStringProviderType properties to the custom MyUserProvider and MyAuditDefaultStringProvider types:

    File: MySolution.Win\Startup.cs

    using DevExpress.Persistent.BaseImpl.EFCore.AuditTrail;
    
    public class ApplicationBuilder : IDesignTimeApplicationFactory {
        public static WinApplication BuildApplication(string connectionString) {
            // ...
            builder.ObjectSpaceProviders
                .AddEFCore(options => options.PreFetchReferenceProperties())
                    .WithAuditedDbContext(contexts => {
                        contexts.Configure<MySolutionEFCoreDbContext, MySolutionAuditingDbContext>(
                            (application, businessObjectDbContextOptions) => {
                                // ...
                            },
                            (application, auditHistoryDbContextOptions) => {
                                // ...
                            },
                            auditTrailOptions => {
                                auditTrailOptions.AuditUserProviderType = typeof(MyUserProvider);
                                auditTrailOptions.AuditDefaultStringProviderType = typeof(MyAuditDefaultStringProvider);
                            });
                    })
                    // ...
        }
        // ...
    }