Entity Framework Core Audit Trial With Audit.Net

Entity Framework Core Audit Trial With Audit.Net

What is Audit Trail?

Audit trail is a record of all user activities within an application. It captures details like who accessed the application, what changes were made, and when they occurred. By maintaining an audit trail, developers can track data modifications, identify unauthorized access, and ensure compliance with industry regulations.

Audit.NET

Audit.NET is a Nuget package that can use to implement Audit Trail in dotnet applications. Instead of implement an audit trial manually, we can use this to easily add audit trial to our application. For Entity Framework Core, they have provided a package called Audit.EntityFramework.Core. In this blog post, let's see how to use this package to implement audit trial in ASP.Net Core application with Entity Framework Core.

Let's Code

First clone this github repository and open project in Visual Studio. I will implement audit trial to this blazor project. In this article I use Blazor Server App using dotnet 6.0.

git clone git@github.com:HRS0986/AuditTrialDemo.git

After opened, you can see folder structure like this

Image description

Now let's install Audit.EntityFramework.Core package. Right click on project name in the solution exporer and click on "Manage Nuget packages". Search for "Audit.EntityFramework.Core".

Image description

They have provided more than one ways to implement audit trial with this package. I will do this in the most easiest way. After installing, go to ApplicationDbContext.

// Data.ApplicationDbContext.cs - Before
 public class ApplicationDbContext : DbContext
 {
     public virtual DbSet<Book> Books { get; set; }

     public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { }

     protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { }

     protected override void OnModelCreating(ModelBuilder modelBuilder)
     {
         modelBuilder.Entity<Book>(entity =>
         {
             entity.Property(e => e.Id).IsRequired().UseIdentityColumn();
             entity.Property(e => e.Title).IsRequired();
             entity.Property(e => e.Description).IsRequired();
             entity.Property(e => e.Author).IsRequired();
         });
     }
 }

We have to inerit our ApplicationDbContext class from the AuditDbContext instead of DbContext.

// Data.ApplicationDbContext.cs - After
 public class ApplicationDbContext : AuditDbContext
 {
     public virtual DbSet<Book> Books { get; set; }

     public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { }

     protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { }

     protected override void OnModelCreating(ModelBuilder modelBuilder)
     {
         modelBuilder.Entity<Book>(entity =>
         {
             entity.Property(e => e.Id).IsRequired().UseIdentityColumn();
             entity.Property(e => e.Title).IsRequired();
             entity.Property(e => e.Description).IsRequired();
             entity.Property(e => e.Author).IsRequired();
         });
     }
 }

Then run the project. Do some action. Delete book, Add new book or Update book. You can see a json file in the project root. If you open that file, you can see a json object like this.

Image description

Now let's create separete folder for audit logs and add configurations to write audit logs in that folder. Add this configuration to program.cs Replace YOUR_FOLDER_PATH with your foder path where you want to save your audit logs. If you want to chage the file name of the json. change {auditEvent.Environment.UserName}_{DateTime.Now.Ticks}.json to you file name

// Program.cs
Audit.Core.Configuration.Setup()
    .UseFileLogProvider(config => config
        .DirectoryBuilder(_ => $@"YOUR_FOLDER_PATH\")
        .FilenameBuilder(auditEvent => $"{auditEvent.Environment.UserName}_{DateTime.Now.Ticks}.json"));

Now our audit trial is working. But some times when your perform update action, the OriginalValue and the NewValue properties can contain same NewValue. This is not what we want. To fix this simple put [AuditDbContext(ReloadDatabaseValues = true)] attribute on the ApplicationDbContext Class like this.

[AuditDbContext(ReloadDatabaseValues = true)]
public class ApplicationDbContext : AuditDbContext
{
    public virtual DbSet<Book> Books { get; set; }
...

This is the easiest way to use Audit.EntityFramework.Core package. You can customize this as you want. They have provided many options with this. If you read their documentation, you can find more details. That's all for now. Happy Coding !

If this blog is helpful to you, don't forget to give a like

Buy Me A Coffee

Connect With Me On hirushafernando.com