Skip to content

ASP.NET Core Integration

RzR edited this page Apr 20, 2026 · 1 revision

ASP.NET Core Integration

The RzR.DataVigil.AspNetCore package plugs into the HTTP pipeline to automatically resolve user identity and request correlation information. Without it, the library falls back to Thread.CurrentPrincipal and System.Diagnostics.Activity, which works fine for workers and console apps but misses the richer context available in a web request.


What it registers

builder.Services.AddAuditTrailAspNetCore();

This single call does three things:

Registration Lifetime What it does
IHttpContextAccessor Singleton Needed to access HttpContext outside of controllers
AspNetCoreUserResolver Scoped Replaces DefaultUserResolver. Reads identity from HttpContext.User
AspNetCoreCorrelationProvider Scoped Replaces DefaultCorrelationProvider. Reads correlation/trace IDs from request headers

User resolution

AspNetCoreUserResolver implements IAuditUserResolver. It uses a fallback chain:

  1. IAuditScopeContext - if someone manually set the user (via SetUser()), that takes priority. This is how you override the HTTP identity in special cases.
  2. HttpContext.User - the normal path for web requests.

When reading from HttpContext.User, it extracts:

Field Source
UserId NameIdentifier claim -> sub claim -> Identity.Name (first match wins)
UserName Identity.Name
IpAddress HttpContext.Connection.RemoteIpAddress
Roles All claims of type ClaimTypes.Role or "role"
Claims All other claims as a Dictionary<string, string>

If there's no authenticated user (anonymous request), the resolver returns null values and the audit record will have empty user fields.


Correlation and trace IDs

AspNetCoreCorrelationProvider implements IAuditCorrelationProvider. It looks for well-known headers first, then falls back to framework-level identifiers.

Correlation ID resolution

Priority Source
1 X-Correlation-Id request header
2 X-Request-Id request header
3 System.Diagnostics.Activity.Current?.Id

Trace ID resolution

Priority Source
1 HttpContext.TraceIdentifier
2 System.Diagnostics.Activity.Current?.TraceId

If your API gateway or load balancer injects X-Correlation-Id, it'll flow through to every audit record automatically. This is helpful for tracing a single user action across multiple services.


Read-flush middleware

When read auditing is enabled, SELECT queries accumulate read entries in a scoped AuditReadCollector throughout the request. The middleware flushes them after the response:

var app = builder.Build();

app.UseRouting();
app.UseAuthorization();
app.UseAuditReadFlush();   // place after routing/auth, before MapControllers
app.MapControllers();

Under the hood it's a simple inline middleware:

  1. Calls next() — lets the rest of the pipeline run
  2. Resolves AuditReadCollector from the request scope
  3. If HasEntries is true, calls FlushAsync() which wraps all collected read entries into an AuditTransaction and pushes it through AuditPipeline.ProcessAsync()

If there were no reads during the request (or read auditing is disabled), the middleware does nothing.


Comparison: with vs. without AspNetCore

Behavior Without AddAuditTrailAspNetCore() With AddAuditTrailAspNetCore()
User resolution IAuditScopeContext -> Thread.CurrentPrincipal -> anonymous IAuditScopeContext -> HttpContext.User
Correlation ID Activity.Current?.Id X-Correlation-Id -> X-Request-Id -> Activity.Current?.Id
Trace ID Activity.Current?.TraceId HttpContext.TraceIdentifier -> Activity.Current?.TraceId
IP address Not available HttpContext.Connection.RemoteIpAddress
Roles/Claims Not extracted Extracted from HttpContext.User.Claims

For worker services and console apps, don't install this package. Use IAuditScopeContext.SetUser() instead — see Advanced Topics.

Clone this wiki locally