Hello,
When a role is removed from a user, we need to track who did it (ie. which AbpUser) and when they did it.
The obvious solution is to redefine the UserRole entity so that it inherits from FullAuditedEntity instead of CreationAuditedEntity, but the UserRole entity is defined in a nuget package so we cannot simply change the definition.
Is there a way to achieve this behavior that I am not seeing?
Also, in this post ismcagdas said "You cannot change UserRole to SoftDelete".
Is this also because the UserRole entity is defined in a nuget package, or is there another reason it cannot be done?
Here is what I have tried so far.
Approach 1: I tried handling this at the database level by setting up a delete trigger on the AbpUserRole table which would insert a record into a AbpUserRoleDeleted table, but I can't think of a way to find out which AbpUser made the deletion with this approach. I can only track when the action happened.
Approach 2: I tried listening for the EntityDeleted domain event on UserRole entities, but it does not seem to get triggered. Interestingly, the EntityUpdated event is triggered when I remove a role from a user, but even assuming that this event would only ever be triggered when a UserRole is deleted, the event data still does not include who made the deletion. If it did, I could manually save the audit information in a separate table just like a database delete trigger would, but this time I would have the AbpUser that was responsible for the deletion.
Approach 3: I tried extending the UserRole entity by following the steps here. I was able to implement the IDeletionAudited interface and generate a migration that creates the associated columns on the AbpUserRoles table, but removing a role from a user performs a hard delete instead of a soft delete so I can't tell if the columns even get populated. I am assuming they do not.
Approach 4: I tried enabling Entity History for the UserRole entity, but it seems to only track when a UserRole entity is created.
I will continue exploring more approaches, but in the meantime I would appreciate any help you can provide with this problem.
Thanks!
10 Answer(s)
-
0
Approach 2: I tried listening for the EntityDeleted domain event on UserRole entities, but it does not seem to get triggered. Interestingly, the EntityUpdated event is triggered when I remove a role from a user, but even assuming that this event would only ever be triggered when a UserRole is deleted,
This is a solution, but because of some changes in EF Core3.x, the event has not been triggered, I will check it.
-
0
Hi maliming,
The project has been built upon the "<PROJECTNAME>-aspnetzero-7.3.1" ZIP archive and is still using EF Core 2.2.6.
~~Also, I couldn't find a way to get the user behind any of the entity events. Is this even possible?~~
~~I found out I can inject AbpSession to get the current user.~~
Turns out AbpSession is already part of the base class.
-
0
Hi @tom.ohle
Does this happen when you remove a role from user in User Edit Modal ?
-
0
-
0
@tom.ohle
Thanks, I will check it.
-
0
I was able to successfully implement the following solution. Do you see any red flags?
src\aspnet-core\src\Company.App.EntityFrameworkCore\EntityFrameworkCore\AppDbContext.cs
namespace Company.App.EntityFrameworkCore { public class AppDbContext : AbpZeroDbContext<Tenant, Role, User, AppDbContext>, IAbpPersistedGrantDbContext { public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { ChangeTracker.StateChanged += OnEntityStateChanged; } private void OnEntityStateChanged(object sender, EntityStateChangedEventArgs e) { if (e.Entry.Entity is UserRole && e.NewState == EntityState.Deleted) { e.Entry.State = EntityState.Modified; e.Entry.CurrentValues["IsDeleted"] = true; e.Entry.CurrentValues["DeletionTime"] = DateTime.Now; e.Entry.CurrentValues["DeleterUserId"] = AbpSession.UserId; } } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<UserRole>().HasQueryFilter(p => !EF.Property<bool>(p, "IsDeleted")); modelBuilder.Entity<UserRole>().Property<bool>("IsDeleted"); modelBuilder.Entity<UserRole>().Property<DateTime?>("DeletionTime").IsRequired(false); modelBuilder.Entity<UserRole>().Property<long?>("DeleterUserId").IsRequired(false); } } }
-
0
hi tom.ohle
We should check why the event of deleting the entity is not triggered.
What is your abp version?
-
0
The project has been built upon the "<PROJECTNAME>-aspnetzero-7.3.1" ZIP archive and is still using EF Core 2.2.6.
-
0
@tom.ohle
I assume you did not upgrade the abp package, I will check it, thank you.
-
0
We should check why the event of deleting the entity is not triggered.
This is a feature of ef. The solution is to use the code in issue or upgrade to ef core 3.0+
https://github.com/dotnet/efcore/issues/10093
I will investigate what the abp framework can do.