I’ve recently found it necessary to set up an audit log because I have some thrilling business requirements that demand I do so. Luckily, it appears that I’m not the first person that had to solve this problem and there was something available for my use. Even better, it looked pretty straightforward to use!
However, there didn’t appear to be a quick explanation to get me up and running in a hurry. That’s usually something I look for because I learn by doing, so I made my own! Importantly, the documentation available is great, I’m really just bringing attention to some specifics so others in my situation might be able to get straight to business. It’s also worth noting that there is just so much documentation available that something pointing you to the relevant bits might have some value.
So what’s the goal? I want to be able to track changes to multiple record types (ie: tables) in the same audit table and be able to identify those records later via some kind of fancy composite key. Later I plan to dump those audit records into a grid with all sorts of fun features like grouping and sorting and whatnot such that examining this information is taken care of by someone else that’ll understand it.
Step one is to install the stuff – Audit.NET and Audit.EntityFramework via the package manager, however you prefer to use it:
PM> Install-Package Audit.NET PM> Install-Package Audit.EntityFramework
That’s how mine looks, anyhow. Your flavor of Entity Framework might be different and, as such, you’d select a different option from the information available here. You may even choose to use a different data provider. In that case, you’re on your own!
I have an established database that I have to work with. So what I aim to do is create a table and then write a model that matches it in C#. After that, I just chunk that model into my data context and get to work. (If anyone has better ideas, I’m definitely open to them.) I’ll omit writing the specific model because it’s only relevant for my use case and, if you’re reading this, you’re probably well and truly familiar with how to construct your own models.
I’m interested, so far, in high level SaveChanges logging. There is a nice guide for that right here. Initially I’ve chosen to change what my data context inherits from – the first method outlined there. I’m not sure what the drawback is, or if there is one. I’m capable of changing the inheritance, and I read that one first, so that’s naturally what I’m doing. My reasoning behind picking this one is that I assumed it would probably work and without additional background information, I decided to try stuff until I ran into an insurmountable problem.
Further, since we’re neck deep in this EntityFramework ecosystem we’re choosing to use the Entity Framework Data Provider. Especially given that I just created the corresponding generic audit table class and added a DbSet<T> for it. It was asking me to set the Entity Framework data provider globally which I’m amenable to, but since I started reading in the middle, frantically looking for immediately relevant information, I’m not sure where to put this.
Maybe in the App_Start -> WebApiConfig.cs class? That seems about right, I do wish to configure something, after all. Interestingly, as far as I can tell, it doesn’t really tell you where to do the configuration. Maybe because it’s flexible? In any event, I choose to start with it in WebApiConfig.cs and I’ll move it around if things don’t work out there. I’m setting it up to use the EF Provider as outlined here, making the necessary changes to suit the project I have at hand (obviously.) This is in keeping with my goal of tracking multiple records in one spot.
Now that I’ve added all that code, I believe that I should have done what was required to enable Auditing in EntityFramework. All that’s left is to test with Postman.
Of course, this testing showed off an error that I wasn’t anticipating (remember data annotations in your models!) But this makes me trust the process because nothing should ever work on the first try. If it does, get suspicious.
After repairing that error, things seem to be working – my generalized audit table received an entry when I did stuff! What a treat! The best part is that all of this is very intelligible C# without any domain specific caveats. This means that adding whatever functionality you want is as straightforward as any other C# work you might find yourself doing.
Something to note is that I will probably be moving the configuration logic out of the WebApiConfig class as soon as I can. It was growing pretty quickly, even for my small test app, and I don’t want that taking up an enormous amount of space in the config. I’d recommend you do the same!