When a user is created through the admin UI with Send confirmation email enabled, the user is created successfully, but no confirmation email is sent.
However, clicking Verify on the "Confirm user" page sends the email successfully.
Error
When processing the user-created event through RabbitMQ, AccountIdentityUserCreatedEventHandler fails while generating the confirmation token, with the following exception:
A DbContext can only be created inside a unit of work!
at Volo.Abp.Identity.AbpSingleActiveTokenProvider.GenerateAsync(...)
at Volo.Abp.Account.Emailing.AccountIdentityUserCreatedEventHandler.HandleEventAsync(...)
The exception occurs before the email is sent, so no confirmation email is generated. RabbitMQ repeatedly retries the failed message.
Change tested
In a test environment, the AccountIdentityUserCreatedEventHandler.cs file in the Volo.Abp.Account.Pro.Public.Application project was modified as follows:
Before:
public async Task HandleEventAsync(IdentityUserCreatedEto eventData)
After:
[UnitOfWork]
public virtual async Task HandleEventAsync(IdentityUserCreatedEto eventData)
The following namespace must also be added:
using Volo.Abp.Uow;
No other changes were made to the method.
After this change, the confirmation email was sent successfully, and the unit of work errors no longer appeared in the logs.
Sources
- Distributed Event Bus – ABP documentation: explains how to use repositories and database operations within distributed event handlers.
- ABP Support: Question 3201: discusses a similar error in a distributed event handler and the missing
virtualmodifier. - Unit of Work – ABP documentation: explains unit of work interception and the requirement for
virtualmethods.
2 Answer(s)
-
0
This happens because the distributed handler (
AccountIdentityUserCreatedEventHandler) runs in the RabbitMQ consumer pipeline without an ambient ABP Unit of Work, but it calls Identity token generation (AbpSingleActiveTokenProvider.GenerateAsync(...)), which needs an EF CoreDbContext. Without a UOW, ABP throws:A DbContext can only be created inside a unit of work!Fix: ensure the handler method is executed inside a Unit of Work via interception:
- Add
[UnitOfWork] - Make the method
virtual(required for ABP’s dynamic proxy interception) - Add
using Volo.Abp.Uow;
Example:
- Add
using System.Threading.Tasks; using Volo.Abp.Uow; public class AccountIdentityUserCreatedEventHandler { [UnitOfWork] public virtual async Task HandleEventAsync(IdentityUserCreatedEto eventData) { // existing handler code (no other changes needed) } }Why the
virtualmatters: ABP applies[UnitOfWork]through dynamic proxy interceptors. If the method isn’tvirtual, the interceptor won’t run, so no UOW is created, and token generation fails. This matches the behavior you observed and also the known pattern from ABP support Q&A.Alternative (works but usually not necessary if interception works): manually begin a UOW inside the handler:
using var uow = _unitOfWorkManager.Begin(); // ... await uow.CompleteAsync();But the recommended approach is the attribute +
virtualso the infrastructure manages it consistently.Links checked:
- https://abp.io/docs/latest/framework/infrastructure/event-bus/distributed
- https://abp.io/docs/latest/framework/architecture/domain-driven-design/unit-of-work
- https://abp.io/support/questions/3201
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.
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post) -
0
Could a member of the support team please review this ticket?
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)