After a couple of busy weeks, I am beginning a new blog series about Auditing a Web API. Here we go ....
Introduction
If you wanted to track every change that occurs in an entity in your domain classes,: for example, you wanted to record when an entity is created, when it is modified, who deleted the entity, and also maybe who was the user who made the change in this practice is called AUDITING.
Here I will show you how you can implement auditing in your application with minimal effort and how to make it reusable. Apart from that, I plan to examine the activities in domain values and behavior changes.
I decide to write a couple of articles to fulfill this requirement.
- Make my domain models auditable using EF core Change Tracker
- With Audit.Net, generate audit logs with evidence for reconstruction and examine activities that have affected specific operations or procedures.
This article is the first one of the audit logging series. Let's integrate the audit properties into domain models.
Audit properties and Audit events
As discussed in the Intro paragraph, We can define
Audit events
- Insert
- Modify
- Delete
The below properties help to track our audit events in the domain model.
Audit properties
- CreatedBy
- CreatedOnUtc
- ModifiedBy
- ModifiedOnUtc
- DeletedBy
- DeletedOnUtc
Note: DeletedBy and DeletedOnUtc properties are always inter-connection with the soft delete functionality.
* Check out my Soft delete feature blog post for good connectivity with this article.
What is the ChangeTracker in EfCore
The ChangeTracker class in Entity Framework Core starts tracking all the entities as soon as they are retrieved using DbContext until they go out of scope.
And EF keeps track of all the changes applied to all the entities and their properties so that it can build and execute appropriate DML statements to the underlying data source.
The ChangeTracker needs to know about the "state" of each object - whether it is new, an existing object that has been modified somehow, or whether it is scheduled for deletion.
ChangeTracker tracks your entity state, whether it is new, modified, or deletion.
The Change Tracker records the current state of an entity using one of five values:
- Added
- Modified
- Deleted
- Unchanged
- Detached
Implementation
First of all, our first step is creating a web API with Entity Framework Core as our base code. Usually, I use a TodoItem project template as the startup sample project. You can find the project template here and check out this blog post that shows how to set it up and how to work.
Based on the sample Todo Item project, you can continue with me.
1. Create a base class including audit properties
As discussed earlier, I am going to define a standard interface, including audit fields.
2. Inherit and implement all properties in entity classes
I want to audit the TodoItem
class. Here I am implementing from the IAuditableEntity
interface.
3. Intercept the SaveChange method to track the above ChangeTracker states.
I implement from SaveChangeInterceptor
and override SavingChangesAsync()
method. It is Called at the start of DbContext.SaveChanges
.
Here I am processing all of the auditable entities available in the change tracker and setting the appropriate values for the modified on the date.'
In the switch statement, identify the actual state of the entities and assign proper values for auditable fields.
4. Register Interceptor and inject to DbContext configurations
In program.cs
we can add these configurations
5. Testing the application and getting results
Last, we can create a request from PostMan and check the result in database tables.
6. Note: Add User Service to get UserId
I am using a UserMockSerivce
Class to get UserId
and UserDetails
who are making changes. You can use your own logic to get user details (Ex: HTTPContextAccessor
with authentication mechanism)
Though
Auditing is an essential cross-cutting feature you should implement on your production product. You wanted to record every action on every entity. It is a must. If you implement Interceptor, you can easily and commonly use it in your distributed applications and entities. Also, you do not need to assign values in every place for the auditable properties.
Source Code
You can find the entire code repository below.
References
Learn something new. Comment your thoughts and share the content.
Happy coding!!
See you again soon. ✌✌