Open Closed

Default ABP user #10112


User avatar
0
sinancondo created

We have a case when we want to add extra logic whenever Update ABP user from admin area and press save . But currently seem like this is a built-in method that's not possible to edit. PUT api/identity/users/{id}

We know there is there already event on updated ABP user but it get called a lot. And we cannot use it unless there is a way to compare old data of user entity with the new data so we can take action based on that such as comparing if Surname was changed from old one to new one .


1 Answer(s)
  • User Avatar
    0
    AI-Bot created
    Support Team ABP Agent
    1. Solution You have three reliable ways to run custom logic specifically when an admin updates a user via PUT api/identity/users/{id} and also compare old vs. new values (e.g., Surname changes):

    A) Override the IdentityUserAppService UpdateAsync (best if you only need to affect this specific endpoint)

    • Create your own application service deriving from IdentityUserAppService and replace the service via dependency injection.
    • Read the existing user first, keep a snapshot, call base.UpdateAsync (or replicate the logic), then compare and run your custom code.
    using System.Threading.Tasks;
    using Volo.Abp.Application.Services;
    using Volo.Abp.DependencyInjection;
    using Volo.Abp.Identity;
    using Volo.Abp.Users;
    
    [Dependency(ReplaceServices = true)]
    public class MyIdentityUserAppService : IdentityUserAppService
    {
        public MyIdentityUserAppService(
            IdentityUserManager userManager,
            IIdentityUserRepository userRepository,
            IIdentityRoleRepository roleRepository)
            : base(userManager, userRepository, roleRepository)
        {
        }
    
        public override async Task<IdentityUserDto> UpdateAsync(Guid id, IdentityUserUpdateDto input)
        {
            // Load current (old) values
            var oldUser = await UserRepository.GetAsync(id);
            var oldSurname = oldUser.Surname;
            var oldEmail = oldUser.Email;
    
            // Call the default update pipeline
            var result = await base.UpdateAsync(id, input);
    
            // Compare with new values
            var newSurname = result.Surname;
            var newEmail = result.Email;
    
            if (!string.Equals(oldSurname, newSurname, StringComparison.Ordinal))
            {
                // Your logic when surname changed
                // e.g., publish a distributed event, call an external service, etc.
            }
    
            if (!string.Equals(oldEmail, newEmail, StringComparison.OrdinalIgnoreCase))
            {
                // Your logic when email changed
            }
    
            return result;
        }
    }
    
    • Registering with [Dependency(ReplaceServices = true)] ensures your app service is used for the /api/identity/users/{id} endpoint. This gives you precise control and easy old/new comparison.

    B) Override/extend IdentityUserManager (when you want to enforce logic at the domain level)

    • If you need invariant business rules regardless of which app service updates users, customize IdentityUserManager, intercept setters or update methods and implement comparisons there. This is more invasive but centralizes the logic. In ABP 8, IdentityUserManager includes IDistributedEventBus injection to publish events on email/username changes.

    C) Use extension to the admin UI and profile UI (if you need UI-driven logic) – not required for backend comparison but helpful when you also need to surface or control fields. For DTO extra properties to flow correctly through built-in services (like profile), ensure module extension mappings are applied to the related DTOs:

    public class MyModule : AbpModule
    {
        private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner();
    
        public override void PostConfigureServices(ServiceConfigurationContext context)
        {
            OneTimeRunner.Run(() =>
            {
                ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToApi(
                    IdentityModuleExtensionConsts.ModuleName,
                    IdentityModuleExtensionConsts.EntityNames.User,
                    getApiTypes: new[] { typeof(IdentityUserDto), typeof(ProfileDto) },
                    createApiTypes: new[] { typeof(IdentityUserCreateDto) },
                    updateApiTypes: new[] { typeof(IdentityUserUpdateDto), typeof(UpdateProfileDto) }
                );
            });
        }
    }
    

    Notes about “events get called a lot” and comparing old/new data:

    • Domain/Event handlers like EntityUpdated are broad and can fire from different code paths. If you only care about the admin PUT endpoint, approach A is the most targeted.
    • If you still prefer events, you can load the previous state before the operation in your app service, attach it to the event payload you publish, or include both old and new in a custom distributed event so handlers can compare safely.
    • For specific changes (like email/username), ABP 8 added distributed events from IdentityUserManager so downstream code can know old values. For other fields like Surname, do the old/new comparison yourself in UpdateAsync as shown.
    1. Sources
    • IdentityUserAppService (default implementation you can replace):
      • https://github.com/abpframework/abp/blob/dev/modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityUserAppService.cs
    • ABP Module System (how to replace services/modules):
      • https://abp.io/docs/latest/framework/architecture/modularity/basics
    • ABP 8.0 migration note about IdentityUserManager publishing distributed events for username/email changes:
      • https://abp.io/docs/latest/release-info/migration-guides/abp-8-0
    • Support thread showing proper DTO extension flow for user/profile (ApplyEntityConfigurationToApi example):
      • https://abp.io/support/questions/3517

    This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.

Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.1.0-preview. Updated on November 17, 2025, 08:31
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.