Skip to content

Getting Started

RzR edited this page Apr 20, 2026 · 1 revision

Getting Started

This page gets you from zero to a working audit trail in the shortest path possible. We'll set up a ASP.NET Core Web API with EF Core and SQL Server. If you're using a different storage backend or hosting model, the Storage Providers and Advanced Topics pages cover those.


1. Install packages

Four packages for the full stack:

<PackageReference Include="RzR.DataVigil.Core" />
<PackageReference Include="RzR.DataVigil.AspNetCore" />
<PackageReference Include="RzR.DataVigil.EFCore" />
<PackageReference Include="RzR.DataVigil.Storage.EfSqlServer" />

Swap EfSqlServer for EfPostgreSql, EfMongoDb, or Storage.File depending on where you want your audit data to end up.


2. Mark entities for auditing

Add the IAuditable marker interface to any entity you want tracked:

using RzR.DataVigil.Abstractions.Contracts;

public class Order : IAuditable
{
    public int Id { get; set; }
    public string CustomerEmail { get; set; }
    public decimal TotalAmount { get; set; }
    public string Status { get; set; }
}

That's it for the entity. Every create, update, and delete on Order will now be captured. Entities without IAuditable are silently ignored - the interceptor doesn't even look at them.

If you need finer control (skip certain actions, exclude specific fields), look at IAuditableEntity on the EF Core Integration page.


3. Register services in Program.cs

using RzR.DataVigil.AspNetCore.Extensions;
using RzR.DataVigil.Core.Extensions;
using RzR.DataVigil.EFCore.Extensions;
using RzR.DataVigil.Storage.EfSqlServer.Extensions;

var builder = WebApplication.CreateBuilder(args);

// Configure the audit trail
builder.Services.AddAuditTrail(options =>
{
    options.EfCore.Intercept<AppDbContext>();
    options.Storage.UseSqlServer(
        builder.Configuration.GetConnectionString("AuditDb"));
});

// Register EF Core interceptors
builder.Services.AddAuditTrailEfCore();

// Register SQL Server audit store
builder.Services.AddAuditTrailSqlServer();

// Register ASP.NET Core integration (user + correlation from HttpContext)
builder.Services.AddAuditTrailAspNetCore();

// Register your DbContext with audit interceptors
builder.Services.AddDbContext<AppDbContext>((sp, opts) =>
{
    opts.UseSqlServer(builder.Configuration.GetConnectionString("AppDb"));
    opts.AddAuditInterceptors(sp);
});

var app = builder.Build();

// Run audit table migrations
app.Services.MigrateAuditSqlServerDb();

app.MapControllers();
app.Run();

The order of the Add* calls matters. AddAuditTrail has to come first because it creates the options that everything else reads. See Architecture - DI Registration Order for details.


4. Add a connection string

{
  "ConnectionStrings": {
    "AppDb": "Server=.;Database=MyApp;Trusted_Connection=true;",
    "AuditDb": "Server=.;Database=MyApp_Audit;Trusted_Connection=true;"
  }
}

The audit tables go into their own database (or at least their own schema). That keeps audit records separate from your application data and makes it harder for someone to accidentally wipe them.


5. Try it out

Create or update an Order through your API. Then query the audit store:

[ApiController]
[Route("api/[controller]")]
public class AuditController : ControllerBase
{
    private readonly IAuditStore _store;
    public AuditController(IAuditStore store) => _store = store;

    [HttpGet]
    public async Task<IActionResult> Get(int skip = 0, int take = 20)
    {
        var result = await _store.QueryAsync(
            new AuditTransactionQuery { Skip = skip, Take = take });

        return result.IsSuccess
            ? Ok(result.Response)
            : StatusCode(500, result.Messages);
    }
}

You should see an AuditTransaction with one or more AuditEntry records, each capturing the entity name, the action (Create/Update/Delete), the primary key, and old/new property values.


What got wired up?

Here's a quick summary of what those five registration calls did behind the scenes:

Call What it registers
AddAuditTrail(...) AuditTrailOptions (singleton), GdprPolicyRegistry + GdprProcessor (singleton), AuditPipeline (scoped), IAuditScopeContext (scoped), default resolvers
AddAuditTrailEfCore() AuditSaveChangesInterceptor (scoped), AuditCommandInterceptor (scoped), AuditReadService (scoped)
AddAuditTrailSqlServer() AuditSqlServerDbContext, SqlServerAuditStore as IAuditStore
AddAuditTrailAspNetCore() IHttpContextAccessor, AspNetCoreUserResolver (replaces default), AspNetCoreCorrelationProvider (replaces default)
AddAuditInterceptors(sp) Wires both interceptors into your DbContextOptionsBuilder

Next steps

Clone this wiki locally