Open Closed

Background Job call aplication service #4450


User avatar
0
jmalla.cp created
  • ABP Framework version: v6.0.1
  • UI type: MVC
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): Tired
  • Exception message and stack trace: 2023-01-30 13:02:35.344 +01:00 [WRN] [] [] Failed to process the job '264': an exception occurred. Retry attempt 4 of 10 will be performed in 00:02:40. Volo.Abp.Authorization.AbpAuthorizationException: Exception of type 'Volo.Abp.Authorization.AbpAuthorizationException' was thrown. at Microsoft.AspNetCore.Authorization.AbpAuthorizationServiceExtensions.CheckAsync(IAuthorizationService authorizationService, AuthorizationPolicy policy) at Volo.Abp.Authorization.MethodInvocationAuthorizationService.CheckAsync(MethodInvocationAuthorizationContext context) at Volo.Abp.Authorization.AuthorizationInterceptor.AuthorizeAsync(IAbpMethodInvocation invocation) at Volo.Abp.Authorization.AuthorizationInterceptor.InterceptAsync(IAbpMethodInvocation invocation) at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func3 proceed) at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo) at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue1.ProceedAsync() at Volo.Abp.GlobalFeatures.GlobalFeatureInterceptor.InterceptAsync(IAbpMethodInvocation invocation) at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func3 proceed) at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo) at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue1.ProceedAsync() at Volo.Abp.Auditing.AuditingInterceptor.ProceedByLoggingAsync(IAbpMethodInvocation invocation, IAuditingHelper auditingHelper, IAuditLogScope auditLogScope) at Volo.Abp.Auditing.AuditingInterceptor.ProcessWithNewAuditingScopeAsync(IAbpMethodInvocation invocation, AbpAuditingOptions options, ICurrentUser currentUser, IAuditingManager auditingManager, IAuditingHelper auditingHelper, IUnitOfWorkManager unitOfWorkManager) at Volo.Abp.Auditing.AuditingInterceptor.ProcessWithNewAuditingScopeAsync(IAbpMethodInvocation invocation, AbpAuditingOptions options, ICurrentUser currentUser, IAuditingManager auditingManager, IAuditingHelper auditingHelper, IUnitOfWorkManager unitOfWorkManager) at Volo.Abp.Auditing.AuditingInterceptor.InterceptAsync(IAbpMethodInvocation invocation) at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func3 proceed) at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo) at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue1.ProceedAsync() at Volo.Abp.Validation.ValidationInterceptor.InterceptAsync(IAbpMethodInvocation invocation) at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func3 proceed) at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo) at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue1.ProceedAsync() at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation) at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func3 proceed) at Cincaporc.WebApp.BackgroundServices.Farms.SyncActiveFarmsWorker.DoWorkAsync(CancellationToken cancellationToken) in C:\Users\jmalla\source\Cincaporc.WebApp\src\Cincaporc.WebApp.BackgroundServices\Farms\SyncActiveFarmsWorker.cs:line 35 at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
  • Steps to reproduce the issue:"

Hi everyone,

I'm having some issues when trying to lunch an aplication service method from background job.

I know, this isn't a good practice, but in this case I need to create a User in a backgrond job, and I can't find this method in any domain service, so I have to call IIdentityUserAppService.CreateAsync()

How can I do it?

Thanks


12 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    and I can't find this method in any domain service

    In this case, create a Domain service. And use it in app service and background job.

  • User Avatar
    0
    jmalla.cp created

    Hi,

    But every time ABP changes the user creation process, aplication service IIdentityUserAppService.CreateAsync(), then I have to change the method of my domain service. And I don't know the exact process of IIdentityUserAppService.CreateAsync() method.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    This is inevitable.

  • User Avatar
    0
    jmalla.cp created

    Hi maliming,

    When I run this methods inside a domain service, throw this exception

    2023-01-31 16:28:42.370 +01:00 [WRN] [] [] Failed to process the job '801': an exception occurred. Retry attempt 6 of 10 will be performed in 00:11:52. Volo.Abp.AbpException: A DbContext can only be created inside a unit of work! at Volo.Abp.Uow.EntityFrameworkCore.UnitOfWorkDbContextProvider1.GetDbContextAsync() at Volo.Abp.Domain.Repositories.EntityFrameworkCore.EfCoreRepository2.EnsureCollectionLoadedAsync[TProperty](TEntity entity, Expression1 propertyExpression, CancellationToken cancellationToken) at Volo.Abp.Domain.Repositories.RepositoryExtensions.EnsureCollectionLoadedAsync[TEntity,TKey,TProperty](IBasicRepository2 repository, TEntity entity, Expression1 propertyExpression, CancellationToken cancellationToken) at Volo.Abp.Identity.IdentityUserStore.AddToRoleAsync(IdentityUser user, String normalizedRoleName, CancellationToken cancellationToken) at Microsoft.AspNetCore.Identity.UserManager1.AddToRoleAsync(TUser user, String role) at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo) at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue1.ProceedAsync() at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation) at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func3 proceed) at Cincaporc.WebApp.ExtendedIdentityUsers.ExtendedIdentityUserManager.CreateOrUpdateIdentityUser(IdentityUserCreateDto input) in C:\Users\jmalla\source\Cincaporc.WebApp\src\Cincaporc.WebApp.Domain\ExtendedIdentityUsers\ExtendedIdentityUserManager.cs:line 95 at Cincaporc.WebApp.ExtendedIdentityUsers.ExtendedIdentityUserImportManager.CreateAllActiveFromExternalServiceAsync(AgentsImportDto input) in C:\Users\jmalla\source\Cincaporc.WebApp\src\Cincaporc.WebApp.Domain\ExtendedIdentityUsers\ExtendedIdentityUserImportManager.cs:line 73 at Cincaporc.WebApp.BackgroundServices.Farms.SyncActiveFarmsWorker.DoWorkAsync(CancellationToken cancellationToken) in C:\Users\jmalla\source\Cincaporc.WebApp\src\Cincaporc.WebApp.BackgroundServices\Farms\SyncActiveFarmsWorker.cs:line 35 at System.Runtime.CompilerServices.TaskAwaiter.GetResult()`

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    A DbContext can only be created inside a unit of work!

    https://docs.abp.io/en/abp/latest/Unit-Of-Work#begin-a-new-unit-of-work

  • User Avatar
    0
    jmalla.cp created

    Hi maliming,

    When I use "Unit of work" then it launch this exception,

    System.InvalidOperationException

    The navigation 'IdentityUser.Roles' cannot be loaded because the entity is not being tracked. Navigations can only be loaded for tracked entities.

    System.InvalidOperationException: The navigation 'IdentityUser.Roles' cannot be loaded because the entity is not being tracked. Navigations can only be loaded for tracked entities. at Microsoft.EntityFrameworkCore.Internal.EntityFinder1.LoadAsync(INavigation navigation, InternalEntityEntry entry, CancellationToken cancellationToken) at Volo.Abp.Domain.Repositories.EntityFrameworkCore.EfCoreRepository2.EnsureCollectionLoadedAsync[TProperty](TEntity entity, Expression1 propertyExpression, CancellationToken cancellationToken) at Volo.Abp.Domain.Repositories.RepositoryExtensions.EnsureCollectionLoadedAsync[TEntity,TKey,TProperty](IBasicRepository2 repository, TEntity entity, Expression1 propertyExpression, CancellationToken cancellationToken) at Volo.Abp.Identity.IdentityUserStore.AddToRoleAsync(IdentityUser user, String normalizedRoleName, CancellationToken cancellationToken) at Microsoft.AspNetCore.Identity.UserManager1.AddToRoleAsync(TUser user, String role) at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo) at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue1.ProceedAsync() at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation) at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed) at Cincaporc.WebApp.ExtendedIdentityUsers.ExtendedIdentityUserImportManager.CreateOrUpdateIdentityUser(IdentityUserCreateDto input) in C:\Users\jmalla\source\Cincaporc.WebApp\src\Cincaporc.WebApp.Domain\ExtendedIdentityUsers\ExtendedIdentityUserImportManager.cs:line 210 at Cincaporc.WebApp.ExtendedIdentityUsers.ExtendedIdentityUserImportManager.CreateAllUsersActiveFromExternalSericeAsync(AgentsImportDto input) in C:\Users\jmalla\source\Cincaporc.WebApp\src\Cincaporc.WebApp.Domain\ExtendedIdentityUsers\ExtendedIdentityUserImportManager.cs:line 181 at Cincaporc.WebApp.BackgroundServices.Farms.SyncActiveFarmsWorker.DoWorkAsync(CancellationToken cancellationToken) in C:\Users\jmalla\source\Cincaporc.WebApp\src\Cincaporc.WebApp.BackgroundServices\Farms\SyncActiveFarmsWorker.cs:line 46 at System.Runtime.CompilerServices.TaskAwaiter.GetResult()

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Please share your SyncActiveFarmsWorker and ExtendedIdentityUserImportManager code.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    System.ArgumentNullException Value cannot be null. (Parameter 'roleNames')

    Please check this line: (await _identityUserManager.SetRolesAsync(user, input.RoleNames)).CheckErrors();

    The input.RoleNames is null.

  • User Avatar
    0
    jmalla.cp created

    System.ArgumentNullException Value cannot be null. (Parameter 'roleNames')

    Please check this line: (await _identityUserManager.SetRolesAsync(user, input.RoleNames)).CheckErrors();

    The input.RoleNames is null.

    Hi,

    I solved It, but now I have this new issue Exception

    Failed
    
    An exception occurred during performance of the job.
    System.InvalidOperationException
    
    The instance of entity type 'IdentityUser' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.
    
    System.InvalidOperationException: The instance of entity type 'IdentityUser' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.
       at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.ThrowIdentityConflict(InternalEntityEntry entry)
       at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.Add(TKey key, InternalEntityEntry entry, Boolean updateDuplicate)
       at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.Add(InternalEntityEntry entry)
       at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.StartTracking(InternalEntityEntry entry)
       at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState oldState, EntityState newState, Boolean acceptChanges, Boolean modifyProperties)
       at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.PaintAction(EntityEntryGraphNode`1 node)
       at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityEntryGraphIterator.TraverseGraph[TState](EntityEntryGraphNode`1 node, Func`2 handleNode)
       at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.AttachGraph(InternalEntityEntry rootEntry, EntityState targetState, EntityState storeGeneratedWithKeySetTargetState, Boolean forceStateWhenUnknownKey)
       at Microsoft.EntityFrameworkCore.DbContext.SetEntityState(InternalEntityEntry entry, EntityState entityState)
       at Microsoft.EntityFrameworkCore.DbContext.SetEntityState[TEntity](TEntity entity, EntityState entityState)
       at Volo.Abp.Domain.Repositories.EntityFrameworkCore.EfCoreRepository`2.UpdateAsync(TEntity entity, Boolean autoSave, CancellationToken cancellationToken)
       at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
       at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync()
       at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
       at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)
       at Volo.Abp.Identity.IdentityUserStore.UpdateAsync(IdentityUser user, CancellationToken cancellationToken)
       at Microsoft.AspNetCore.Identity.UserManager`1.UpdateUserAsync(TUser user)
       at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
       at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync()
       at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
       at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)
       at Microsoft.AspNetCore.Identity.UserManager`1.SetUserNameAsync(TUser user, String userName)
       at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
       at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync()
       at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
       at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)
       at Cincaporc.WebApp.ExtendedIdentityUsers.ExtendedIdentityUserImportManager.UpdateAsync(Guid id, IdentityUserUpdateDto input) in C:\Users\jmalla\source\Cincaporc.WebApp\src\Cincaporc.WebApp.Domain\ExtendedIdentityUsers\ExtendedIdentityUserImportManager.cs:line 101
       at Cincaporc.WebApp.ExtendedIdentityUsers.ExtendedIdentityUserImportManager.CreateOrUpdateIdentityUser(IdentityUserCreateDto input) in C:\Users\jmalla\source\Cincaporc.WebApp\src\Cincaporc.WebApp.Domain\ExtendedIdentityUsers\ExtendedIdentityUserImportManager.cs:line 212
       at Cincaporc.WebApp.ExtendedIdentityUsers.ExtendedIdentityUserImportManager.CreateAllUsersActiveFromExternalSericeAsync(AgentsImportDto input) in C:\Users\jmalla\source\Cincaporc.WebApp\src\Cincaporc.WebApp.Domain\ExtendedIdentityUsers\ExtendedIdentityUserImportManager.cs:line 190
       at Cincaporc.WebApp.BackgroundServices.Farms.SyncActiveFarmsWorker.ImportAllAgentsAsync() in C:\Users\jmalla\source\Cincaporc.WebApp\src\Cincaporc.WebApp.BackgroundServices\Farms\SyncActiveFarmsWorker.cs:line 67
       at Cincaporc.WebApp.BackgroundServices.Farms.SyncActiveFarmsWorker.DoWorkAsync(CancellationToken cancellationToken) in C:\Users\jmalla\source\Cincaporc.WebApp\src\Cincaporc.WebApp.BackgroundServices\Farms\SyncActiveFarmsWorker.cs:line 46
       at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
    
    
  • User Avatar
    0
    jmalla.cp created

    And my code is

    Code

    public class SyncActiveFarmsWorker : HangfireBackgroundWorkerBase
        {
            private readonly FarmImportManager _farmImportManager;
            private readonly ExtendedIdentityUserImportManager _extendedIdentityUserImportManager;
            private readonly BreedingImportManager _breedingImportManager;
            private readonly IRepository<Farm, Guid> _farmRepository;
            private readonly IdentityUserManager _identityUserManager;
            private readonly IObjectMapper _objectMapper;
    
            public SyncActiveFarmsWorker(
                FarmImportManager farmImportManager,
                BreedingImportManager breedingImportManager,
                IRepository<Farm, Guid> farmRepository,
                ExtendedIdentityUserImportManager extendedIdentityUserImportManager,
                IdentityUserManager identityUserManager,
                IObjectMapper objectMapper)
            {
                RecurringJobId = nameof(SyncActiveFarmsWorker);
                CronExpression = Cron.Daily(20);
                _farmImportManager = farmImportManager;
                _breedingImportManager = breedingImportManager;
                _farmRepository = farmRepository;
                _extendedIdentityUserImportManager = extendedIdentityUserImportManager;
                _identityUserManager = identityUserManager;
                _objectMapper = objectMapper;
            }
    
            public override async Task DoWorkAsync(CancellationToken cancellationToken = default)
            {
                Logger.LogInformation("Executed Sync Agents..!");
                // Pending to recive information from support of ABP
                await ImportAllAgentsAsync();
                Logger.LogInformation("Executed Sync farms..!");
                await _farmImportManager.ImportAllActiveFarmsAsync();
                Logger.LogInformation("Executed Sync last active breedings..!");
                await ImportLastActiveBreedingsAsync();
            }
    
            private async Task ImportLastActiveBreedingsAsync()
            {
                List<Farm> farms = await _farmRepository.GetListAsync();
    
                foreach (var farm in farms)
                {
                    await _breedingImportManager.ImportLastActiveBreedingsByFarmIdAsync(farm.EkonClientCodeId);
                }
            }
    
            private async Task ImportAllAgentsAsync()
            {
                AgentsImportDto input = new AgentsImportDto();
                input.AgentType = AgentType.Veterinarian;
                await _extendedIdentityUserImportManager.CreateAllUsersActiveFromExternalSericeAsync(input);
    
                input = new AgentsImportDto();
                input.AgentType = AgentType.Visitor;
    
                await _extendedIdentityUserImportManager.CreateAllUsersActiveFromExternalSericeAsync(input);
    
                input = new AgentsImportDto();
                input.AgentType = AgentType.Haulier;
    
                await _extendedIdentityUserImportManager.CreateAllUsersActiveFromExternalSericeAsync(input);
            }
    
        }
    
    public class ExtendedIdentityUserImportManager : DomainService
        {
            private readonly AgentExternalService _agentExternalService;
            private readonly IOptions<IdentityOptions> _identityOptions;
            private readonly IdentityUserManager _identityUserManager;
            private readonly IUnitOfWorkManager _unitOfWorkManager;
            private readonly IObjectMapper _objectMapper;
            private readonly IDistributedEventBus _distributedEventBus;
    
            public ExtendedIdentityUserImportManager(
                IOptions<IdentityOptions> identityOptions,
                IUnitOfWorkManager unitOfWorkManager,
                IObjectMapper objectMapper,
                IDistributedEventBus distributedEventBus,
                IdentityUserManager identityUserManager
                )
            {
                _agentExternalService = new AgentExternalService();
                _identityOptions = identityOptions;
                _unitOfWorkManager = unitOfWorkManager;
                _objectMapper = objectMapper;
                _distributedEventBus = distributedEventBus;
                _identityUserManager = identityUserManager;
            }
    
            public async Task<IdentityUserCreateDto> GetAgentToImport(AgentImportDto input)
            {
                AgentDto agent = new AgentDto();
                ExternalService.Contracts.Agents.AgentType agentType = (ExternalService.Contracts.Agents.AgentType)Enum.Parse(typeof(ExternalService.Contracts.Agents.AgentType), input.AgentType.ToString());
    
                if (!_agentExternalService.HaveService(agentType))
                    throw new ServiceIsNotReady().WithData("Name", agentType.ToString());
    
                agent = await _agentExternalService.Services[agentType].GetAsync(input.AgentCode);
    
                IdentityUserCreateDto identityUserCreateDto = GetIdentityUserCreateDtoFromExternalAgent(agent, input.AgentType);
    
                return identityUserCreateDto;
            }
    
            private IdentityUserCreateDto GetIdentityUserCreateDtoFromExternalAgent(AgentDto agent, AgentType agentType)
            {
                IdentityUserCreateDto identityUserCreateDto = new IdentityUserCreateDto();
                identityUserCreateDto.Name = agent.Name;
                identityUserCreateDto.Surname = agent.Surname;
                identityUserCreateDto.SetAgentType(agentType);
                identityUserCreateDto.SetAgentErpId(agent.Code);
                identityUserCreateDto.UserName = agent.Username;
                identityUserCreateDto.Email = agent.Email;
                identityUserCreateDto.SetDefaultPassword();
    
                return identityUserCreateDto;
            }
    
            public async Task<List<IdentityUserCreateDto>> GetAllActiveAgents(AgentType agentTypeToImport)
            {
                ExternalService.Contracts.Agents.AgentType agentType = (ExternalService.Contracts.Agents.AgentType)Enum.Parse(typeof(ExternalService.Contracts.Agents.AgentType), agentTypeToImport.ToString());
    
                if (!_agentExternalService.HaveService(agentType))
                    throw new ServiceIsNotReady().WithData("Name", agentType.ToString());
    
                List<AgentDto> agentsToImport = await _agentExternalService.Services[agentType].GetAllActiveAsync();
    
                if (agentsToImport == null || agentsToImport.Count == 0)
                    return new List<IdentityUserCreateDto>();
    
                return agentsToImport.Select(x => GetIdentityUserCreateDtoFromExternalAgent(x, agentTypeToImport)).ToList();
            }
    
            public async Task<IdentityUserDto> UpdateAsync(Guid id, IdentityUserUpdateDto input)
            {
                await _identityOptions.SetAsync();
    
                var user = await _identityUserManager.GetByIdAsync(id);
    
                using (var uow = _unitOfWorkManager.Begin(
                    requiresNew: true, isTransactional: false
                ))
                {
                    user.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp);
    
                    (await _identityUserManager.SetUserNameAsync(user, input.UserName)).CheckErrors();
                    
                    await UpdateUserByInput(user, input);
                    
                    input.MapExtraPropertiesTo(user);
                    
                    (await _identityUserManager.UpdateAsync(user)).CheckErrors();
    
                    await uow.CompleteAsync();
                }
    
                var userDto = _objectMapper.Map<IdentityUser, IdentityUserDto>(user);
    
                return userDto;
            }
    
            private async Task UpdateUserByInput(IdentityUser user, IdentityUserCreateOrUpdateDtoBase input)
            {
                if (!string.Equals(user.Email, input.Email, StringComparison.InvariantCultureIgnoreCase))
                {
                    (await _identityUserManager.SetEmailAsync(user, input.Email)).CheckErrors();
                }
    
                if (!string.Equals(user.PhoneNumber, input.PhoneNumber, StringComparison.InvariantCultureIgnoreCase))
                {
                    (await _identityUserManager.SetPhoneNumberAsync(user, input.PhoneNumber)).CheckErrors();
                }
    
                (await _identityUserManager.SetLockoutEnabledAsync(user, input.LockoutEnabled)).CheckErrors();
    
                user.Name = input.Name;
                user.Surname = input.Surname;
                (await _identityUserManager.UpdateAsync(user)).CheckErrors();
                user.SetIsActive(input.IsActive);
                
                (await _identityUserManager.SetRolesAsync(user, input.RoleNames)).CheckErrors();
            }
    
            public async Task<IdentityUserDto> CreateAsync(IdentityUserCreateDto input)
            {
                await _identityOptions.SetAsync();
    
                var user = new IdentityUser(
                    GuidGenerator.Create(),
                    input.UserName,
                    input.Email,
                    CurrentTenant.Id
                );
    
                input.MapExtraPropertiesTo(user);
    
                using (var uow = _unitOfWorkManager.Begin(
                    requiresNew: true, isTransactional: false
                ))
                {
                    (await _identityUserManager.CreateAsync(user, input.Password)).CheckErrors();
                    
                    await UpdateUserByInput(user, input);
                    
                    (await _identityUserManager.UpdateAsync(user)).CheckErrors();
                    
                    await uow.CompleteAsync();
                }
    
                await _distributedEventBus.PublishAsync(new IdentityUserCreatedEto()
                {
                    Id = user.Id,
                    Properties =
                    {
                        { "SendConfirmationEmail", input.SendConfirmationEmail.ToString().ToUpper() },
                        { "AppName", "MVC" }
                    }
                });
    
                var userDto = _objectMapper.Map<IdentityUser, IdentityUserDto>(user);
    
                return userDto;
            }
    
            public async Task CreateAllUsersActiveFromExternalSericeAsync(AgentsImportDto input)
            {
                List<IdentityUserCreateDto> identityUsersToImport = await GetAllActiveAgents(input.AgentType);
    
                foreach (var identityUserToImport in identityUsersToImport)
                {
                    AssignRoleToUserFromAgentType(identityUserToImport);
    
                    await CreateOrUpdateIdentityUser(identityUserToImport);
                }
            }
    
            private void AssignRoleToUserFromAgentType(IdentityUserCreateDto identityUserToImport)
            {
                if (identityUserToImport.RoleNames == null)
                    identityUserToImport.RoleNames = new string[1];
    
                identityUserToImport.RoleNames[0] = identityUserToImport.GetAgentType().GetRoleName();
            }
    
            private async Task<IdentityUserDto> CreateOrUpdateIdentityUser(IdentityUserCreateDto input)
            {
                IdentityUser identityUser = await _identityUserManager.FindByNameAsync(input.UserName);
    
                Guid? userId = identityUser?.Id;
    
                if (identityUser != null && !identityUser.IsActive)
                {
                    var userUpdateDto = _objectMapper.Map<IdentityUserCreateDto, IdentityUserUpdateDto>(input);
    
                    IdentityUserDto userUpdated = await UpdateAsync(identityUser.Id, userUpdateDto);
                    userId = userUpdated.Id;
                }
                else if (identityUser == null)
                {
                    IdentityUserDto createdUser = await CreateAsync(input);
                    userId = createdUser.Id;
                }
    
                return _objectMapper.Map<IdentityUser, IdentityUserDto>(await _identityUserManager.GetByIdAsync((Guid)userId));
            }
        }
    

    Thanks for all

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    move your GetByIdAsync code into the new uow scope.

    public async Task UpdateAsync(Guid id, IdentityUserUpdateDto input)
    {
        using (var uow = _unitOfWorkManager.Begin(
                   requiresNew: true, isTransactional: false
               ))
        {
            await _identityOptions.SetAsync();
    
            var user = await _identityUserManager.GetByIdAsync(id);
            
            user.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp);
    
            (await _identityUserManager.SetUserNameAsync(user, input.UserName)).CheckErrors();
    
            await UpdateUserByInput(user, input);
    
            input.MapExtraPropertiesTo(user);
    
            (await _identityUserManager.UpdateAsync(user)).CheckErrors();
    
            await uow.CompleteAsync();
            
            var userDto = _objectMapper.Map(user);
    
            return userDto;
        }
    }
    
  • User Avatar
    0
    jmalla.cp created

    Hi,

    Now Everythink works fine.

    Thanks for all.

Made with ❤️ on ABP v9.1.0-preview. Updated on December 12, 2024, 07:15