Home > OS >  Audit.Net Get the name of the method which called .SaveChangesAsync()
Audit.Net Get the name of the method which called .SaveChangesAsync()

Time:01-29

I have the following Setup

Audit.Core.Configuration.Setup() // Triggered on a database save.
    .UseEntityFramework(ef => ef
        .AuditTypeExplicitMapper(m => m
            .Map<Item, AuditLog>()
            .AuditEntityAction<AuditLog>((evt, entry, auditEntity) =>
            {
                auditEntity.AuditData = entry.ToJson();
                auditEntity.AuditDate = DateTime.UtcNow;
                auditEntity.CallingMethod = "Calling Method"; <-- Where I need the calling method.
            })
        )
    );
    public async Task DoSomeWork() {  //<--- I want to get "DoSomeWork"
        // Some work..
        await dbConn.SaveChangesAsync();
        return updated;
    }

How can I get access to the method which called .saveChangesAsync so I know where it was triggered from? I've checked using StackTrace however that is flooded with library level frames which are not very helpful and I can't find the correct parent method.

I see in evt there is a that it provides a calling parent name, however that is just one level up so is just the "SaveChangesAsync" method.

Thanks

CodePudding user response:

If you can change the code that calls SaveChangesAsync and you are inheriting your DbContext from AuditDbContext (High-Level SaveChanges interception), then you could add a new SaveChanges method with an optional parameter decorated with [CallerMemberName] and store the caller member name in a custom field of the AuditEvent.

For example:

public class YourDbContext : AuditDbContext
{
    public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default) 
        => throw new NotImplementedException("Should call SaveChangesAuditAsync");

    public Task<int> SaveChangesAuditAsync([CallerMemberName] string memberName = "", CancellationToken cancellationToken = default)
    {
        this.AddAuditCustomField("Caller", memberName);
        return base.SaveChangesAsync(cancellationToken);
    }
}

So, in your AuditEntityAction you can get the caller member name from the custom field:

    ...
    .AuditEntityAction<AuditLog>((evt, entry, auditEntity) =>
    {
        auditEntity.CallingMethod = evt.CustomFields["Caller"];
    })

Now your DoSomeWork() must call the new method:

public async Task DoSomeWork() 
{
    ...
    await dbConn.SaveChangesAuditAsync();
    return updated;
}
  • Related